package com.lingniu.ingest.identity;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lingniu.ingest.api.ProtocolId;
import com.lingniu.ingest.identity.config.VehicleIdentityProperties;
import org.h2.jdbcx.JdbcDataSource;
import org.junit.jupiter.api.Test;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static org.assertj.core.api.Assertions.assertThat;

class MySqlVehicleIdentityServiceJdbcTest {

    @Test
    void plateVinBindingIsQueryableThroughRealJdbc() throws Exception {
        JdbcDataSource dataSource = new JdbcDataSource();
        dataSource.setURL("jdbc:h2:mem:" + UUID.randomUUID()
                + ";MODE=MySQL;DATABASE_TO_UPPER=false;DB_CLOSE_DELAY=-1");

        VehicleIdentityProperties.Mysql mysql = new VehicleIdentityProperties.Mysql();
        mysql.setTableName("vehicle_identity_binding");
        MySqlVehicleIdentityService service = new MySqlVehicleIdentityService(
                dataSource,
                mysql,
                new ObjectMapper());

        service.bind(new VehicleIdentityBinding(
                ProtocolId.JT808,
                "LNVIN00000061001",
                "13079961001",
                "dev61001",
                "粤B61001",
                Map.of(
                        "province", "44",
                        "city", "4401",
                        "maker", "maker-a",
                        "deviceType", "type-a",
                        "plateColor", "1")));

        try (Connection connection = dataSource.getConnection();
             Statement statement = connection.createStatement()) {
            ResultSet binding = statement.executeQuery("""
                    SELECT vin, phone, device_id, plate, province, city, maker, device_type, plate_color
                    FROM vehicle_identity_binding
                    WHERE protocol = 'JT808' AND phone = '13079961001'
                    """);
            assertThat(binding.next()).isTrue();
            assertThat(binding.getString("vin")).isEqualTo("LNVIN00000061001");
            assertThat(binding.getString("phone")).isEqualTo("13079961001");
            assertThat(binding.getString("device_id")).isEqualTo("dev61001");
            assertThat(binding.getString("plate")).isEqualTo("粤B61001");
            assertThat(binding.getString("province")).isEqualTo("44");
            assertThat(binding.getString("city")).isEqualTo("4401");
            assertThat(binding.getString("maker")).isEqualTo("maker-a");
            assertThat(binding.getString("device_type")).isEqualTo("type-a");
            assertThat(binding.getString("plate_color")).isEqualTo("1");

            List<String> columns = new ArrayList<>();
            ResultSet bindingColumns = connection.getMetaData()
                    .getColumns(null, null, "vehicle_identity_binding", null);
            while (bindingColumns.next()) {
                columns.add(bindingColumns.getString("COLUMN_NAME"));
            }
            assertThat(columns).contains(
                    "protocol",
                    "phone",
                    "device_id",
                    "plate",
                    "vin",
                    "metadata_json");
        }

        assertThat(service.resolve(new VehicleIdentityLookup(
                ProtocolId.JT808, "", "13079961001", "", "")).vin())
                .isEqualTo("LNVIN00000061001");
        assertThat(service.resolve(new VehicleIdentityLookup(
                ProtocolId.JT808, "", "", "dev61001", "")).vin())
                .isEqualTo("LNVIN00000061001");
        assertThat(service.resolve(new VehicleIdentityLookup(
                ProtocolId.JT808, "", "", "", "粤B61001")).vin())
                .isEqualTo("LNVIN00000061001");
    }
}
