/* *****************************************************************************
 * File:      cli_commands.c
 * Date:      07-11-2025
 * Author:    Andrew Levido
 *
 * Copyright 2026 Imbrius Pty Ltd - All Rights Reserved
 *
 ******************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "cli_commands.h"
#include "cli.h"
#include <stdlib.h>
#include <string.h>
#include "analog.h"
#include "app.h"

/* Global Variables ----------------------------------------------------------*/


/* Private Functions ---------------------------------------------------------*/
void cli_power_callback(char* args);
void cli_load_callback(char* args);
void cli_drive_callback(char* args);
void cli_read_callback(char* args);

/* Public Functions ----------------------------------------------------------*/
void cli_register_commands(void)
{
  cli_register_command("power", "Set power node { power r|g|b|off] {hi|lo} }", true, cli_power_callback);
  cli_register_command("load", "Set load node { load r|g|b|off] value(mv) }", true, cli_load_callback);
  cli_register_command("drive", "Set drive node { drive r|g|b|off] v|i value(mv or µA) }", true, cli_drive_callback);
  cli_register_command("read", "Read voltage or current { read r|g|b|i }", true, cli_read_callback);
}

/* File System   -------------------------------------------------------------*/

void cli_power_callback(char * args)
{
  char * token;

  // Retrieve argument 1 
  token = cli_get_token(args, 1);

  if(strcmp(token, "r") == 0) {
    an_set_matrix(NODE_POWER, LEAD_RED);
  }
  else if (strcmp(token, "g") == 0) {
    an_set_matrix(NODE_POWER, LEAD_GREEN);
  }
  else if (strcmp(token, "b") == 0) {
    an_set_matrix(NODE_POWER, LEAD_BLUE);
  }
  else if (strcmp(token, "off") == 0) {
    an_set_matrix(NODE_POWER, LEAD_NONE);
    an_set_power(false);
    return;
  }
  else {
    cli_printf("\tInvalid parameter: use 'r', 'g', 'b' of 'off'\n");
    return;
  }
  // Retrieve argument 2
  token = cli_get_token(args, 2);

  if(strcmp(token, "lo") == 0) {
    an_set_power(false);
  }
  else if (strcmp(token, "hi") == 0) {
    an_set_power(true);
  }
   else if (strcmp(token, "off") == 0) {
    an_set_matrix(NODE_POWER, LEAD_NONE);
  }
  else {
    cli_printf("\tInvalid parameter: use 'hi' or 'lo'\n");
  }
}

void cli_load_callback(char * args)
{
  char * token;
  char * end_ptr;
  int32_t value; 

  // Retrieve argument 1 
  token = cli_get_token(args, 1);

  if(strcmp(token, "r") == 0) {
    an_set_matrix(NODE_LOAD, LEAD_RED);
  }
  else if (strcmp(token, "g") == 0) {
    an_set_matrix(NODE_LOAD, LEAD_GREEN);
  }
  else if (strcmp(token, "b") == 0) {
    an_set_matrix(NODE_LOAD, LEAD_BLUE);
  }
  else if (strcmp(token, "off") == 0) {
    an_set_matrix(NODE_LOAD, LEAD_NONE);
    an_set_load_mv(0);
    return;
  }
  else {
    cli_printf("\tInvalid parameter: use 'r', 'g', 'b' or 'off'\n");
    return;
  }

  // Retrieve argument 2 
  token = cli_get_token(args, 2);

  // validate value
   value = strtol(token, &end_ptr, 10);
  if((end_ptr == token) || (*end_ptr != 0) || (value > 12000) || (value < 0)) {
    cli_printf("\tBad value:  0 <= value <= 12000");
    return;
  }
  an_set_load_mv(value);
}

void cli_drive_callback(char * args)
{
  char * token;
  char * token2;
  char * end_ptr;
  int32_t value; 

  // Retrieve argument 1 
  token = cli_get_token(args, 1);

  if(strcmp(token, "r") == 0) {
    an_set_matrix(NODE_DRIVE, LEAD_RED);
  }
  else if (strcmp(token, "g") == 0) {
    an_set_matrix(NODE_DRIVE, LEAD_GREEN);
  }
  else if (strcmp(token, "b") == 0) {
    an_set_matrix(NODE_DRIVE, LEAD_BLUE);
  }
  else if (strcmp(token, "off") == 0) {
    an_set_matrix(NODE_DRIVE, LEAD_NONE);
    an_set_drive_mv(0);
    return;
  }
  else {
    cli_printf("\tInvalid parameter: use 'r', 'g', 'b' or 'off'\n");
    return;
  }

  // Retrieve argument 2 and 3
  token = cli_get_token(args, 2);
  token2 = cli_get_token(args, 3);

  if(strcmp(token, "v") == 0) {
    // validate value
    value = strtol(token2, &end_ptr, 10);
    if((end_ptr == token) || (*end_ptr != 0) || (value > 12000) || (value < 0)) {
      cli_printf("\tBad value:  0 <= value <= 12000)\n");
      return;
    }
    an_set_drive_mv(value);
  }
  else if (strcmp(token, "i") == 0){
   /// validate value
    value = strtol(token2, &end_ptr, 10);
    if((end_ptr == token) || (*end_ptr != 0) || (value > 4000) || (value < -4000)) {
      cli_printf("\tBad value:  -4000 <= value <= 4000)\n");
      return;
    }
    if((value > 250) || (value < -250)) {
      an_set_drive_ua(value);
    }
    else {
      an_set_drive_na(value * 1000);
    }
  }
  else {
    cli_printf("\tInvalid parameter: use 'v' or 'i'\n");
    return;
  }
}

void cli_read_callback(char* args)
{
   char * token;
 
  // Retrieve argument 1 
  token = cli_get_token(args, 1);

  if(strcmp(token, "r") == 0) {
    cli_printf("\t Vred = %+i mV", an_get_red_mv());
  }
  else if (strcmp(token, "g") == 0) {
    cli_printf("\t Vgrn = %+i mV", an_get_green_mv());
  }
  else if (strcmp(token, "b") == 0) {
    cli_printf("\t Vblu = %+i mV", an_get_blue_mv());
  }
  else if (strcmp(token, "i") == 0) {
    cli_printf("\t Ild = %+i µA", an_get_load_ua());
  }
  else if (strcmp(token, "i") == 0) {
    an_set_matrix(NODE_POWER, LEAD_NONE);
    an_set_load_mv(0);
    return;
  }
  else {
    cli_printf("\tInvalid parameter: use 'r', 'g', 'b' or 'i'\n");
    return;
  }
}


/* End cli_commands */