#pragma once

#include "global.h"

#include <SQLiteCpp/Statement.h>

#include <cstdint>
#include <filesystem>
#include <iosfwd>
#include <memory>
#include <optional>
#include <string>
#include <vector>

namespace External_Database_Utils {

struct Header_Csv_Resource_Config {
    std::string name;
    std::string cache_file_name;
    std::string download_url;
    std::string description;
    std::uint64_t update_interval_seconds{};
    std::vector<std::string> columns;
    std::vector<std::string> primary_key_columns;
    char delimiter = ',';
};

struct Schema_Only_Resource_Config {
    std::string name;
    std::string description;
    std::uint64_t update_interval_seconds{};
    std::string create_table_sql;
    std::vector<std::string> primary_key_columns;
};

std::string quote_identifier(const std::string& value);
std::string normalize_key(std::string value);
std::optional<std::string> normalize_field(std::string value);
void bind_optional(SQLite::Statement& statement,
                   int index,
                   const std::optional<std::string>& value);
bool read_csv_row(std::istream& input,
                  std::vector<std::string>& fields,
                  char delimiter);
std::string make_upsert_sql(const std::string& table_name,
                            const std::vector<std::string>& columns,
                            const std::vector<std::string>& primary_key_columns);
void download_to_file(std::string url, const std::filesystem::path& target_file);
void decompress_gzip(const std::filesystem::path& gzip_file,
                     const std::filesystem::path& target_file);
std::size_t import_header_csv(SQLite::Database& db,
                              const std::filesystem::path& source_file,
                              const std::string& table_name,
                              const std::vector<std::string>& columns,
                              const std::vector<std::string>& primary_key_columns,
                              char delimiter = ',');

std::unique_ptr<External_Resources> make_header_csv_resource(
    Header_Csv_Resource_Config config);
std::unique_ptr<External_Resources> make_schema_only_resource(
    Schema_Only_Resource_Config config);
std::unique_ptr<External_Resources> make_tar1090_aircraft_resource(
    std::string name,
    std::string description,
    std::uint64_t update_interval_seconds);

}  // 命名空间 External_Database_Utils
