#include "Config_Default.h"
#include "Target_Defaults.h"
namespace {
void configure_source_display(Data_Source_Map_Display_Data& display, std::string color,
                              std::uint32_t aircraft_pixel_size, std::uint32_t base_station_pixel_size,
                              double aircraft_scale, bool show_call_sign, bool show_fly_status) {
    display.color = std::move(color);
    display.aircraft_pixel_size = aircraft_pixel_size;
    display.base_station_pixel_size = base_station_pixel_size;
    display.aircraft_scale = aircraft_scale;
    display.base_station_scale = 0.44;
    display.show_call_sign = show_call_sign;
    display.show_fly_status = show_fly_status;
}
std::shared_ptr<Dll_Data_Source> make_dll_source() {
    auto source = std::make_shared<Dll_Data_Source>();
    source->key = "lzy_dll";
    source->set_enabled(true);
    source->settings.write([](auto& value) {
        value.base_station_has_valid_position = true;
        configure_source_display(value.map_display.map2d, "#454641", 34, 30, 2.0, false, false);
        configure_source_display(value.map_display.map3d, "#454641", 50, 100, 1.0, false, false);
        value.lat = 37.433547;
        value.lon = 121.40873;
        value.alt = 2300.0;
        value.ignore_msg_time = true;
    });
    source->specific.write([](auto& value) {
        value.library_path = config_default::dsp_library_path;
        value.function_name = "adsb_read";
        value.data_type = File_Data_Type::BIN_Blank_Text;
        value.buffer_size = 200000;
    });
    return source;
}
#if defined(ECAP_TARGET_WINDOWS)
std::shared_ptr<File_Data_Source> make_file_source() {
    auto source = std::make_shared<File_Data_Source>();
    source->key = "aaaa";
    source->set_enabled(false);
    source->settings.write([](auto& value) {
        configure_source_display(value.map_display.map2d, "#d1a54c", 50, 100, 2.0, true, true);
        configure_source_display(value.map_display.map3d, "#d1a54c", 50, 100, 2.0, true, true);
        value.lat = 37.0;
        value.lon = 121.0;
        value.alt = 1000.0;
        value.ignore_msg_time = true;
    });
    source->specific.write([](auto& value) {
        value.file_path = config_default::file_source_path;
        value.data_type = File_Data_Type::BIN_Blank_Text;
        value.play_mode = Play_Mode::loop;
    });
    return source;
}
#endif
void configure_feed(Data_Feed& feed, std::string type, std::string key, bool enabled, Output_Data_Format format,
                    bool use_status, Mode_S_Output_Type mode_s_output_type, bool use_mode_ac, bool sbs_only_pos) {
    feed.type = std::move(type);
    feed.key = std::move(key);
    feed.set_enabled(enabled);
    feed.source_key = "lzy_dll";
    feed.output_format.write([&](auto& value) {
        value.type = format;
        value.use_status = use_status;
        value.mode_s_output_type = mode_s_output_type;
        value.use_mode_ac = use_mode_ac;
        value.sbs_only_pos = sbs_only_pos;
    });
}
std::shared_ptr<Data_Feed_TCP_Server> make_tcp_server_feed(std::string key, bool enabled, Output_Data_Format format,
                                                           bool use_status, Mode_S_Output_Type mode_s_output_type,
                                                           bool use_mode_ac, bool sbs_only_pos, std::uint16_t port,
                                                           std::size_t user_buffer_size,
                                                           std::size_t system_buffer_size) {
    auto feed = std::make_shared<Data_Feed_TCP_Server>();
    configure_feed(*feed, "Data_Feed_TCP_Server", std::move(key), enabled, format, use_status, mode_s_output_type,
                   use_mode_ac, sbs_only_pos);
    feed->specific.write([&](auto& value) {
        value.port = port;
        value.connect_user_buffer_size = user_buffer_size;
        value.connect_system_buffer_size = system_buffer_size;
    });
    return feed;
}
}
Default_Config_File make_default_mode_acs_config(const std::filesystem::path& directory) {
    Mode_ACS_Config config;
    config.settings.write([](auto& value) {
        value.timeout_seconds = 160;
        value.max_speed_m_s = 1000;
        value.wait_process_msg = true;
        value.time_space_filter = true;
        value.speed_filter = true;
        value.max_track_point_size = 20000;
        value.mode_s_max_num = 700000;
        value.mode_other_max_num = 10000;
        value.report_data_feed_msg_mum = 10000;
        value.default_min_aircraft_list_num = 10;
    });
    config.data_source_config.map.push_back(make_dll_source());
#if defined(ECAP_TARGET_WINDOWS)
    config.data_source_config.map.push_back(make_file_source());
#endif
    config.data_feed_config.map.push_back(make_tcp_server_feed("Port_10003", true, Output_Data_Format::BIN, true,
                                                               Mode_S_Output_Type::ALL_Mode_S, true, true, 10003,
                                                               409600, 409600));
    auto udp_server = std::make_shared<Data_Feed_UDP_Server>();
    configure_feed(*udp_server, "Data_Feed_UDP_Server", "22333", false, Output_Data_Format::BIN, false,
                   Mode_S_Output_Type::ALL_Mode_S, false, false);
    udp_server->specific.write([](auto& value) { value.port = 50001; });
    config.data_feed_config.map.push_back(udp_server);
    auto udp_client = std::make_shared<Data_Feed_UDP_Client>();
    configure_feed(*udp_client, "Data_Feed_UDP_Client", "Port_10004", false, Output_Data_Format::AVR, false,
                   Mode_S_Output_Type::DF_11_17_18, false, true);
    udp_client->specific.write([](auto& value) {
        value.port = 30004;
        value.url = "192.168.1.75";
    });
    config.data_feed_config.map.push_back(udp_client);
    auto tcp_client = std::make_shared<Data_Feed_TCP_Client>();
    configure_feed(*tcp_client, "Data_Feed_TCP_Client", "Port_10005", false, Output_Data_Format::BIN, true,
                   Mode_S_Output_Type::NO_POS_Mode_S, true, true);
    tcp_client->specific.write([](auto& value) {
        value.url = "192.168.1.167";
        value.port = 10005;
    });
    config.data_feed_config.map.push_back(tcp_client);
    config.data_feed_config.map.push_back(make_tcp_server_feed(
    "Port_30003", false, Output_Data_Format::SBS, false, Mode_S_Output_Type::ALL_Mode_S, true, true, 30003, 0, 0));
    return {Config_Section::mode_acs, directory / "mode_acs.json", config.to_base_json()};
}
