#include "lip.h"
#include "lip_sample_mdns_test.h"
#include <stdio.h>
#include <stdlib.h>
#include "ltimer.h"

static const char *f_host_basename = "lip_test";
static char f_hostname[64];
static const char *f_probe_test_basename = "lip_probetest";
static char f_probe_test_name[64];

static const char *f_test_shared_name  = "lip_test_shared";
static const char *f_host_cname = "lip_test_cname";

static const char *f_tst_str[] = {"str1", "str1", "str3"};
static const t_lip_dns_rdata_txt f_tst_text = {
    .format = LIP_DNS_TXT_FORMAT_LIST,
    .str_cnt = 3,
    .str = f_tst_str
};

static const char *f_tst_str1 = "teststr1";
static const char *f_tst_str2 = "teststr123";
static const char *f_tst_str3 = "teststr3";
static const char *f_tst_str4 = "teststr4";

static const t_lip_dns_rdata_txt f_tst_txt1 = {
    .format = LIP_DNS_TXT_FORMAT_LIST,
    .str_cnt = 1,
    .str = &f_tst_str1
};

static const t_lip_dns_rdata_txt f_tst_txt2 = {
    .format = LIP_DNS_TXT_FORMAT_LIST,
    .str_cnt = 1,
    .str = &f_tst_str2
};

static const t_lip_dns_rdata_txt f_tst_txt3 = {
    .format = LIP_DNS_TXT_FORMAT_LIST,
    .str_cnt = 1,
    .str = &f_tst_str3
};

static const t_lip_dns_rdata_txt f_tst_txt4 = {
    .format = LIP_DNS_TXT_FORMAT_LIST,
    .str_cnt = 1,
    .str = &f_tst_str4
};



static t_lip_dns_txt_keyval f_srv_txt_vals[] = {
    {"txtver", "1"},
    {"serial", "1234"},
    {"descr",  "test service"}
};

static const char *f_srv_instanse  = "test_inst";
static const char *f_srv_name  = "_test_srv._tcp";
static const char *f_srv_instanse2 = "test_inst2";

static t_ltimer f_remove_tst_tmr;
static int f_remove_tst;

static void f_itoa(unsigned val, char *str) {
    unsigned div, digts;
    const unsigned max_div = (1UL << (sizeof(int)*8-1))/10;

    /* определяем кол-во цифр */
    for (digts=1, div=10; (val >= div) && (div < max_div); digts++, div*=10)
    {}

    if (val >= div) {
        digts++;
    } else {
        div/=10;
    }

    while (div!=0) {
        char c;
        c = val/div;
        val %= div;
        *str++ = '0' + c;
        div/=10;
    }
}

static void f_make_new_name(t_lip_dns_name *new_name, char *buf, const char *basename, unsigned num) {
    int len = strlen(basename);
    f_itoa(num+1, &buf[len]);
    new_name->name = buf;
    new_name->parent = lip_mdns_get_parent_domain();
}

static void f_mdns_name_conflict_cb(const t_lip_dns_name *name, t_lip_dns_name *new_name, unsigned conflict_cnt) {
    if (name->name == f_hostname) {
        f_make_new_name(new_name, f_hostname, f_host_basename, conflict_cnt);
    } else if (name->name == f_probe_test_name) {
        f_make_new_name(new_name, f_probe_test_name, f_probe_test_basename, conflict_cnt);
    }
}


void lip_sample_mdns_test_init(void) {
    t_lip_dns_rr rr;
    t_lip_dns_name name;
    name.parent = lip_mdns_get_parent_domain();

    strcpy(f_hostname, f_host_basename);
    lip_mdns_set_hostname(f_hostname, f_mdns_name_conflict_cb);



    rr.rclass = LIP_DNS_CLASS_IN;
    rr.type = LIP_DNS_RRTYPE_TXT;
    rr.ttl = LIP_MDNS_DEFAULT_TTL;

    name.name = f_test_shared_name;

    lip_mdns_rr_add(&name, &rr, &f_tst_text, 0, NULL);
    lip_mdns_rr_add(&name, &rr, &f_tst_txt1, 0, NULL);
    lip_mdns_rr_add(&name, &rr, &f_tst_txt3, 0, NULL);
    lip_mdns_rr_add(&name, &rr, &f_tst_txt4, 0, NULL);



    strcpy(f_probe_test_name, f_probe_test_basename);
    name.name = f_probe_test_name;

    lip_mdns_rr_add(&name, &rr, &f_tst_txt1, LIP_MDNS_ADDFLAGS_UNIQUE, f_mdns_name_conflict_cb);
    lip_mdns_rr_add(&name, &rr, &f_tst_txt2, LIP_MDNS_ADDFLAGS_UNIQUE, NULL);
    lip_mdns_rr_add(&name, &rr, &f_tst_txt3, LIP_MDNS_ADDFLAGS_UNIQUE, NULL);



    lip_dnssd_register_local(f_srv_instanse, f_srv_name, 113, f_mdns_name_conflict_cb,
                             f_srv_txt_vals, sizeof(f_srv_txt_vals)/sizeof(f_srv_txt_vals[0]));
    lip_dnssd_register_local(f_srv_instanse2, f_srv_name, 114, f_mdns_name_conflict_cb,
                             f_srv_txt_vals, sizeof(f_srv_txt_vals)/sizeof(f_srv_txt_vals[0]));

    name.name = f_host_cname;
    rr.type = LIP_DNS_RRTYPE_CNAME;
    lip_mdns_rr_add(&name, &rr, lip_mdns_get_host_domain(), 0, NULL);


    ltimer_set(&f_remove_tst_tmr, LTIMER_MS_TO_CLOCK_TICKS(30*1000));
    f_remove_tst = 1;
}


void lip_sample_mdns_test_pull(void) {
    if (f_remove_tst && ltimer_expired(&f_remove_tst_tmr)) {
        t_lip_dns_name name;
        name.parent = lip_mdns_get_parent_domain();
        name.name = f_probe_test_name;
        lip_mdns_rr_remove(&name, LIP_DNS_RRTYPE_TXT, &f_tst_txt2);
        f_remove_tst = 0;
    }
}
