#include "terminal_user.h"
#include "cmsis_os.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>


SbsTerminal sbsTerminal;
Terminal* pTerminal;

osThreadId terminaltTaskHandle;
void vTerminal(void const *params);


//
SbsTerminal::SbsTerminal() :
    Terminal()
{}


//
void SbsTerminal::configure()
{
    Terminal::configure();
    pTerminal = &sbsTerminal;
    
    osMessageQDef(TerminalQueue, 20, uint8_t);
    m_dataQueue = osMessageCreate(osMessageQ(TerminalQueue), NULL);
      
    osThreadDef(Terminal, vTerminal, osPriorityNormal, 0, 2*128);
    terminaltTaskHandle = osThreadCreate(osThread(Terminal), NULL);
}


//
int SbsTerminal::execute(int argc, const char * const *argv)
{
    if (argc <= 0) {
        return -1;
    }
    if (strcmp(argv[0], "help") == 0) {
        return help(argc, argv);
    }
    else if (strcmp(argv[0], "version") == 0) {
        return version(argc, argv);
    }
    else if (strcmp(argv[0], "clear") == 0) {
        return clear(argc, argv);
    }    
    else if (strcmp(argv[0], "reset") == 0) {
        NVIC_SystemReset();
    }

    // ---------------------------------------------------------------------- //
    else {
        printeol();
        printll("Uncknown command [oO]");
        return 0;
    }
}


void SbsTerminal::sigint() {
}


//Колбэк, который может быть вызван при подключении
void SbsTerminal::connectCallback() 
{
    clearScreen();
    printll("SBS terminal.");
  
    //Тут выводим полезную при подключении информацию
    printeol();
    printll("For help type 'help'.");
    insert('\r');    
}
    

//
int SbsTerminal::help(int argc, const char * const *argv)
{
    printeol();
    printeol();
    printl ("You can use the following commands:");
    printl ("  version        Print nSBS software version");
    printl ("  os             Print FreeRTOS statistics");
    printl ("  stat           Print FreeRTOS common controller statistics");
    printl ("  ifconfig       Print net params");
    printl ("  set_ip         Set IP address");
    printl ("  set_mask       Set netmask");
    printl ("  set_gw         Set gateway");
    printl ("  set_usb_ip     Set IP address for RNDIS");
    printl ("  set_usb_mask   Set netmask for RNDIS");
    printl ("  set_usb_gw     Set gateway for RNDIS");
    printl ("  reset          Controller reset");
    printl ("  boot           Go to DFU mode");
    printl ("  clear          Clear terminal screen");
    printl ("  ls             List of files");
    printl ("  cat            Cat file");
    printl ("  del            Delete file");
    printl ("  format         Format file system");
    printl ("  phy            dump phy reisters");
    printl ("  fpga_boot      Prepare FPGA for download mode");
    printll("  update         update main firmaware");
    printeol();
    
    help_connection();
    return 0;
}


// Справка по поводу соединения
int SbsTerminal::help_connection() 
{
    return 0;
}


//
int SbsTerminal::version(int argc, const char * const *argv) 
{
    printeol();
    //print(FW_VERSION);
    printeol();
    return 0;
}


//
int SbsTerminal::clear(int argc, const char * const *argv)
{
    if ((argc > 1) && (strcmp(argv[1], "help") == 0))  
    {
        printeol();
        printl("Clear terminal screen");      
        printeol();
        printeol();
        return 0;
    }
    clearScreen();
    return 0;
}



//
void SbsTerminal::put_byte(char byte)
{
    osMessagePut(m_dataQueue, byte, 0);
}

//
void vTerminal(void const *params)
{
    osEvent event;
    
    for (;;)
    {
        event = osMessageGet(sbsTerminal.m_dataQueue, 1000);
       
        if (event.status == osEventMessage) {
            sbsTerminal.insert(event.value.v);
        }
    }  
}
