/*
    acairdk.c - airscatter.dk provider for AS
    Copyright 2023 Ladislav Vaiz <ok1zia@nagano.cz>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.
*/

#include "ac.h"
#include <libzia.h>
#include "header.h"
#include "main.h"
#include "tsdl.h"

int acs_airdk_init(struct acs* acs) {
    acs->airdk_http_timer = zselect_timer_new(zsel, 1000, acs_airdk_http_timer, acs);

    acs->load_from_main_thread = acs_airdk_load_from_main_thread;
#ifdef Z_HAVE_SDL
    acs->plot_info = acs_airdk_plot_info;
#endif
    acs->dead_minutes = 4; //TODO cfg->ac_airdk_minutes + 3;
    return 0;
}

void acs_airdk_free(struct acs* acs) {
    if (acs->airdk_http_timer) zselect_timer_kill(zsel, acs->airdk_http_timer);
    zhttp_free(acs->airdk_http);
    g_free(acs->airdk_http_error);
}

void acs_airdk_http_timer(void* arg) {
    struct acs* acs = (struct acs*)arg;
    acs->airdk_http_timer = 0;

    time_t now = time(NULL);
    struct tm utc;
    gmtime_r(&now, &utc);

    dbg("\n%02d:%02dz acs_airdk_http_timer\n", utc.tm_hour, utc.tm_min);
    const char* mywwl = ctest ? ctest->pwwlo : cfg->pwwlo;
    if (cfg->ac_centerwwl != NULL && strlen(cfg->ac_centerwwl) >= 4) mywwl = cfg->ac_centerwwl;
    double lng = qth(mywwl, 0) * 180.0 / M_PI;
    double lat = qth(mywwl, 1) * 180.0 / M_PI;

    // https://www.virtualradarserver.co.uk/Documentation/Formats/AircraftList.aspx
    char* url = g_strdup_printf("http://airscatter.dudez.no:18090/VirtualRadar/AircraftList.json?lat=%6.4f&lng=%6.4f&fDstU=600", lat, lng);
    dbg("airdk url=%s\n", url);

    acs->airdk_http = zhttp_init();
    zhttp_auth_basic(acs->airdk_http, "tucnak", "EpKNG7"); // please do not use this password in other program, ask OV3T for your access
    zhttp_get(acs->airdk_http, zsel, url, acs_airdk_downloaded_callback, acs);
    g_free(url);
}

void acs_airdk_downloaded_callback(struct zhttp* http) {
    char* data;
    int remains;
    struct acs* acs = (struct acs*)http->arg;

    //dbg("acs_airdk_downloaded_callback\n");

    if (http->state == ZHTTPST_ERROR && http->errorstr) {
        dbg("ERROR acs_airdk_downloaded_callback: %s\n", http->errorstr);
        g_free(acs->airdk_http_error);
        acs->airdk_http_error = g_strdup(http->errorstr);
        zhttp_free(http);
        acs->airdk_http = NULL;
    }
    else {
        if (http_is_content_type(http, "application/json")) {
            char* content_length = http_get_header(http, "Content-Length");
            dbg("OK acs_airdk_downloaded_callback  Content-Length=%s   inflated length=%d\n", content_length != NULL ? content_length : "???", http->response->len - http->dataofs);
            data = g_new(char, http->response->len + 1);
            zbinbuf_getstr(http->response, http->dataofs, data, http->response->len + 1);

            

            zhttp_free(http);
            acs->airdk_http = NULL;

            MUTEX_LOCK(acs->sh);
            g_free(acs->sh.data);
            acs->sh.data = data;
            MUTEX_UNLOCK(acs->sh);

            zg_free0(acs->airdk_http_error);

            remains = /*TODOcfg->ac_airdk_minutes*/ 1 * 60000;
            acs->airdk_http_timer = zselect_timer_new(zsel, remains, acs_airdk_http_timer, acs);
            return;
        }
        else {
            dbg("ERROR acs_airdk_downloaded_callback: Bad Content-Type\n");
            g_free(acs->airdk_http_error);
            acs->airdk_http_error = g_strdup("Bad Content-Type");
        }
    }

    remains = 60000; // if error retry after 1 minute (longer, maybe server can decrease remaining if reply failed in the middle)
    acs->airdk_http_timer = zselect_timer_new(zsel, remains, acs_airdk_http_timer, acs);

}

void acs_airdk_load_from_main_thread(struct acs* acs, const char* data) {
    struct zjson* json = zjson_init(data);
    struct zjson* acList = zjson_get_array(json, "acList");
    int n = 0, added = 0;
    while (1) {
        struct zjson* one = zjson_get_object(acList, NULL);
        if (one == NULL) break;

        n++;

        int Alt = zjson_get_int(one, "Alt", 0);
        int asl = Alt * 0.3048;
        if (asl < cfg->ac_minalt) {
            zjson_free(one);
            continue;
        }

        double lat = zjson_get_double(one, "Lat", NAN) * M_PI / 180.0;
        double lon = zjson_get_double(one, "Long", NAN) * M_PI / 180.0;

        /*double qrb, qtf;
        hw2qrbqtf(acs->th.myh, acs->th.myw, lon, lat, &qrb, &qtf);
        if (qrb > 600) {
            zjson_free(one);
            continue;
        }*/


        char* Icao = zjson_get_str(one, "Icao", NULL);
        if (Icao == NULL) {
            zjson_free(one);
            continue;
        }

        struct ac* ac = g_new0(struct ac, 1);
        g_strlcpy(ac->id, Icao, AC_ID_MAXLEN);
        g_free(Icao);

        ac->w = lat;
        ac->h = lon;

        ac->qtfdir = (zjson_get_int(one, "Trak", 0) - 90) * M_PI / 180.0;

        ac->asl = asl;
        ac->feets = Alt;

        int Spd = zjson_get_int(one, "Spd", 0);

        ac->knots = Spd;
        ac->speed = ac->knots * 1.852;


        char* callsign = zjson_get_str(one, "Call", NULL);
        if (callsign != NULL) {
            g_strlcpy(ac->callsign, callsign, AC_CALLSIGN_MAXLEN);
            g_free(callsign);
        }

        double PosTime = zjson_get_double(one, "PosTime", 0.0);
        ac->when = (int)(PosTime / 1000.0);

        char* type = zjson_get_str(one, "Type", NULL);
        if (type != NULL) {
            g_strlcpy(ac->icaotype, type, AC_ICAOTYPE_MAXLEN);
            g_free(type);
        }

        ac_fill_wingspan(acs, ac);

        g_ptr_array_add(acs->th.acs, ac);
        added++;
        zjson_free(one);
    }

    dbg("downloaded %d, added %d\n", n, added);
    zjson_free(acList);
    zjson_free(json);
}

#ifdef Z_HAVE_SDL
void acs_airdk_plot_info(struct subwin* sw, SDL_Rect* area, struct acs* acs) {
    SDL_Surface* surface = sdl->screen;
    int c;

    if (acs->airdk_http_error != NULL) {
        c = z_makecol(252, 0, 0);
        zsdl_printf(surface, area->x + 50, area->y + 5, c, 0, ZFONT_TRANSP | ZFONT_OUTLINE, TRANSLATE("Airscatter.dk error: %s"), acs->airdk_http_error);
        return;
    }
}
#endif