#include "bsk_tftp_pfs.h"

#include <string.h>

const char bsk_tftpd_mfs_status_query[]="$status$";
const char bsk_tftpd_mfs_list_query[]="$list$";

bsk_download_site_t* bsk_tftp_mfs_site_;
static int site_n;

static char mfs_site_list[2014];

static char* make_list_string(int n)
{
    const bsk_download_site_t* s=&bsk_tftp_mfs_site_[n];

    strcpy(mfs_site_list, s->name);
    strcat(mfs_site_list, "@");
    strcat(mfs_site_list, s->address);
    strcat(mfs_site_list, ":");
    for(int i=0; i<bsk_download_site_t::k_max_partitions; ++i)
    {
        if (s->partitions[i].name[0]==0)
            break;
        if (s->partitions[i].flags)
        {
            static char ptmp[8];
            char* p=ptmp;
            uint32_t flags=s->partitions[i].flags;
            if (flags & bsk_download_partition_t::part_hidden)
            {
                *p='-';
                ++p;
            }
            if (flags & bsk_download_partition_t::part_default)
            {
                *p='+';
                ++p;
            }
            flags=flags & ~(0x0FF);
            if (flags==bsk_download_partition_t::part_fsbl)
            {
                *p='!';
                ++p;
            }
            else if (flags & bsk_download_partition_t::part_recovery)
            {
                *p='?';
                ++p;
            }
            else if (flags==bsk_download_partition_t::part_operative)
            {
                *p='*';
                ++p;
            }
            *p=0;
            strcat(mfs_site_list, ptmp);
        }
        strcat(mfs_site_list, s->partitions[i].name);
        strcat(mfs_site_list, "|");
    }
    return mfs_site_list;
}

int bsk_tftpd_mfs_set_site(struct bsk_download_site_t* s, int n)
{
    bsk_tftp_mfs_site_=s;
    site_n=n;
    return 0;
}

const char* bsk_tftpd_mfs_get_list(int n)
{
    return make_list_string(n);
}

const char* bsk_tftpd_mfs_query(int n, const char* name)
{
    if (strcmp(name, "$list$")==0)
        return make_list_string(n); //mfs_site_list;
    if (name[0]=='?')
    {
        for(int i=0; i<bsk_download_site_t::k_max_partitions; ++i)
        {
            bsk_download_partition_t* p=&bsk_tftp_mfs_site_->partitions[i];
            if (p->name[0]==0)
                break;
            if (strcmp(&name[1], p->name)==0)
            {
               strcpy(mfs_site_list, "?");
               strcat(mfs_site_list, p->name);
               strcat(mfs_site_list, ":");
               strcat(mfs_site_list, p->contents.version);
               return mfs_site_list;
            }
        }
    }
    return 0;
}

static char tmp[1024];

bsk_download_partition_t* bsk_tftp_mfs_decode_filename(unsigned int entry_id, const char* name, const char** fname)
{
    bsk_download_partition_t* p=0;

    if (fname)
        *fname=name;
    const char* fn=name;

    if (name[0]!='$')
        return 0;

    strncpy(tmp, &name[1], sizeof tmp);
    char* pn=strtok(tmp, ":");
    if (pn)
    {
        fn=strtok(0, "\n");

        bsk_download_partition_t* t=bsk_tftp_mfs_site_[entry_id].partitions;
        for(int i=0; i<bsk_download_site_t::k_max_partitions; ++i)
        {
            if (t[i].name[0]==0)
                break;
            if (strnicmp(t[i].name, pn, sizeof t[i].name)==0)
            {
                p=&t[i];
                break;
            }
        }
    }
    if (fname)
        *fname=fn;

    if (p==0)
        return bsk_tftp_mfs_invalid_partition;
    return p;
}

int bsk_tftp_mfs_decode_site(bsk_download_site_t* site, const char* str)
{
    strncpy(tmp, str, sizeof tmp);

    memset(site, 0, sizeof *site);
    //Extract name
    char* n=strtok(tmp, ":");
    if (!n)
        return 1;

    unsigned int pn=0;
    for(char* p=strtok(0, "|"); p; p=strtok(0, "|"), ++pn)
    {
        bsk_download_partition_t* pp=&site->partitions[pn];
        pp->flags=0;
        if (p[0]=='-')
        {
            pp->flags|=bsk_download_partition_t::part_hidden;
            ++p;
        }
        if (p[0]=='+')
        {
            pp->flags|=bsk_download_partition_t::part_default;
            ++p;
        }
        if (p[0]=='*')
        {
            pp->flags|=bsk_download_partition_t::part_operative;
            ++p;
        }
        else if (p[0]=='?')
        {
            pp->flags|=bsk_download_partition_t::part_recovery;
            ++p;
        }
        else if (p[0]=='!')
        {
            pp->flags|=bsk_download_partition_t::part_fsbl;
            ++p;
        }
        strncpy(pp->name, p, sizeof pp->name);
    }
    //site->num_of_partitions=pn;
    char* pa=strtok(n, "@");
    if (pa)
    {
        char* pa=strtok(0, "@");
        if (pa)
            strncpy(site->address, pa, sizeof site->address);
    }
    strncpy(site->name, n, sizeof site->name);
    return 0;
}


