#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <libgen.h>
#include <unistd.h>

typedef enum {HELP,CHK,CMD} Mode_t;


uint8_t ucCalculateChecksum( const char *pcCommandString )
{
  uint32_t uiRunningTotal = 0; 
  uint32_t i;

  /*Calculate checksum*/
  for( i = 0; i < strlen( pcCommandString ); i++) {

    // Add character to running total
    uiRunningTotal += ( uint32_t ) pcCommandString[i]; }

    // Mask the lower byte and return the value to the caller
    return (uint8_t) ( uiRunningTotal & 0xFF);
}

void printHelp(const char *pname)
{
    printf("\n");
    printf("Usage : %s '<dspl_cmd>'\n",pname);
    printf("-a : all (command)\n");
    printf("-c : checksum only\n");
    printf("-h : help\n");
    printf("\n");
}
void parseArgs(int argc, char **argv, Mode_t *mode, char **cmd)
{
    int opt;
    while ((opt = getopt(argc, argv, "hac")) != -1) {
        switch (opt) {
                case 'c':
                *mode=CHK;
                break;
                case 'a':
                *mode=CMD;
                break;
                case 'h':
            default: /* '?' */
                printHelp(argv[0]);
                exit(EXIT_FAILURE);
                break;
        }
    }
    if (optind >= argc) {
        printf("\n");
        fprintf(stderr, "Expected argument after options\n");
        printHelp(argv[0]);
        exit(EXIT_FAILURE);
    }
    *cmd=argv[optind];
    return;
}

int main(int argc, char **argv)
{
  int retval=-1;
    char* cmd=NULL;
    Mode_t mode=CHK;
    uint8_t cs;
    
    parseArgs(argc,argv,&mode, &cmd);
    cs=ucCalculateChecksum(cmd);
    switch(mode){
            case CHK:
            printf("%02X\n",cs);
            retval=0;
            break;
            
            case CMD:
            printf("%s%02X\n",cmd,cs);
            retval=0;
            break;
        default:
            printHelp(argv[0]);
            break;
    }

    return 0;
}
