/** @file
This file contains the PcdValue structure definition.

Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>

This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "CommonLib.h"
#include "PcdValueCommon.h"

typedef enum {
  PcdDataTypeBoolean,
  PcdDataTypeUint8,
  PcdDataTypeUint16,
  PcdDataTypeUint32,
  PcdDataTypeUint64,
  PcdDataTypePointer
} PCD_DATA_TYPE;

typedef struct {
  CHAR8          *SkuName;
  CHAR8          *DefaultValueName;
  CHAR8          *TokenSpaceGuidName;
  CHAR8          *TokenName;
  CHAR8          *DataType;
  CHAR8          *Value;
  PCD_DATA_TYPE  PcdDataType;
} PCD_ENTRY;

PCD_ENTRY  *PcdList;
UINT32     PcdListLength;

VOID
STATIC
RecordToken (
  UINT8   *FileBuffer,
  UINT32  PcdIndex,
  UINT32  TokenIndex,
  UINT32  TokenStart,
  UINT32  TokenEnd
  )
{
  UINT8  *Token;
  
  Token = malloc (TokenEnd - TokenStart + 1);
  memcpy (Token, &FileBuffer[TokenStart], TokenEnd - TokenStart);
  Token[TokenEnd - TokenStart] = 0;
  switch (TokenIndex) {
  case 0:
    PcdList[PcdIndex].SkuName = Token;
    break;
  case 1:
    PcdList[PcdIndex].DefaultValueName = Token;
    break;
  case 2:
    PcdList[PcdIndex].TokenSpaceGuidName = Token;
    break;
  case 3:
    PcdList[PcdIndex].TokenName = Token;
    break;
  case 4:
    PcdList[PcdIndex].DataType = Token;
    if (strcmp (Token, "BOOLEAN") == 0) {
      PcdList[PcdIndex].PcdDataType = PcdDataTypeBoolean;
    } else if (strcmp (Token, "UINT8") == 0) {
      PcdList[PcdIndex].PcdDataType = PcdDataTypeUint8;
    } else if (strcmp (Token, "UINT16") == 0) {
      PcdList[PcdIndex].PcdDataType = PcdDataTypeUint16;
    } else if (strcmp (Token, "UINT32") == 0) {
      PcdList[PcdIndex].PcdDataType = PcdDataTypeUint32;
    } else if (strcmp (Token, "UINT64") == 0) {
      PcdList[PcdIndex].PcdDataType = PcdDataTypeUint64;
    } else {
      PcdList[PcdIndex].PcdDataType = PcdDataTypePointer;
    }
    break;
  case 5:
    PcdList[PcdIndex].Value = Token;
    break;
  }
}

int
STATIC
LookupPcdIndex (
  CHAR8  *SkuName             OPTIONAL,
  CHAR8  *DefaultValueName    OPTIONAL,
  CHAR8  *TokenSpaceGuidName,
  CHAR8  *TokenName
  )
{
  UINT32  Index;
  
  if (SkuName == NULL) {
    SkuName = "DEFAULT";
  }
  if (DefaultValueName == NULL) {
    DefaultValueName = "DEFAULT";
  }
  for (Index = 0; Index < PcdListLength; Index++) {
    if (strcmp(PcdList[Index].TokenSpaceGuidName, TokenSpaceGuidName) != 0) {
      continue;
    }
    if (strcmp(PcdList[Index].TokenName, TokenName) != 0) {
      continue;
    }
    if (strcmp(PcdList[Index].SkuName, SkuName) != 0) {
      continue;
    }
    if (strcmp(PcdList[Index].DefaultValueName, DefaultValueName) != 0) {
      continue;
    }
    return Index;
  }
  return -1;
}

UINT64
__PcdGet (
  CHAR8  *SkuName             OPTIONAL,
  CHAR8  *DefaultValueName    OPTIONAL,
  CHAR8  *TokenSpaceGuidName,
  CHAR8  *TokenName
  )
{
  int    Index;
  UINT8  *End;
  
  Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
  if (Index < 0) {
    fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
    exit (EXIT_FAILURE);
  }
  switch (PcdList[Index].PcdDataType) {
  case PcdDataTypeBoolean:
  case PcdDataTypeUint8:
  case PcdDataTypeUint16:
  case PcdDataTypeUint32:
    return (UINT64)strtoul(PcdList[Index].Value, &End, 16);
    break;
  case PcdDataTypeUint64:
    return (UINT64)strtoul(PcdList[Index].Value, &End, 16);
    break;
  case PcdDataTypePointer:
    fprintf (stderr, "PCD %s.%s.%s.%s is structure.  Use PcdGetPtr()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
    exit (EXIT_FAILURE);
    break;
  }
  return 0;
}

VOID
__PcdSet (
  CHAR8   *SkuName             OPTIONAL,
  CHAR8   *DefaultValueName    OPTIONAL,
  CHAR8   *TokenSpaceGuidName,
  CHAR8   *TokenName,
  UINT64  Value
  )
{
  int    Index;
  
  Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
  if (Index < 0) {
    fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
    exit (EXIT_FAILURE);
  }
  free(PcdList[Index].Value);
  PcdList[Index].Value = malloc(20);
  switch (PcdList[Index].PcdDataType) {
  case PcdDataTypeBoolean:
    if (Value == 0) {
      strcpy (PcdList[Index].Value, "0x00");
    } else {
      strcpy (PcdList[Index].Value, "0x01");
    }
    break;
  case PcdDataTypeUint8:
    sprintf(PcdList[Index].Value, "0x%02x", (UINT8)(Value & 0xff));
    break;
  case PcdDataTypeUint16:
    sprintf(PcdList[Index].Value, "0x%04x", (UINT16)(Value & 0xffff));
    break;
  case PcdDataTypeUint32:
    sprintf(PcdList[Index].Value, "0x%08x", (UINT32)(Value & 0xffffffff));
    break;
  case PcdDataTypeUint64:
    sprintf(PcdList[Index].Value, "0x%016llx", Value);
    break;
  case PcdDataTypePointer:
    fprintf (stderr, "PCD %s.%s.%s.%s is structure.  Use PcdSetPtr()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
    exit (EXIT_FAILURE);
    break;
  }
}

VOID *
__PcdGetPtr (
  CHAR8   *SkuName             OPTIONAL,
  CHAR8   *DefaultValueName    OPTIONAL,
  CHAR8   *TokenSpaceGuidName,
  CHAR8   *TokenName,
  UINT32  *Size
  )
{
  int    Index;
  UINT8   *Value;
  UINT8   *Buffer;
  UINT8   *End;
  UINT8   Byte;
  
  Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
  if (Index < 0) {
    fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
    exit (EXIT_FAILURE);
  }
  switch (PcdList[Index].PcdDataType) {
  case PcdDataTypeBoolean:
  case PcdDataTypeUint8:
  case PcdDataTypeUint16:
  case PcdDataTypeUint32:
  case PcdDataTypeUint64:
    fprintf (stderr, "PCD %s.%s.%s.%s is a value.  Use PcdGet()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
    exit (EXIT_FAILURE);
    break;
  case PcdDataTypePointer:
    Value = &PcdList[Index].Value[1];
    printf ("Value = %s\n", PcdList[Index].Value);
    for (*Size = 0, Byte = (UINT8) strtoul(Value, &End, 16); Value != End; Byte = (UINT8) strtoul(Value, &End, 16), *Size = *Size + 1) {
      printf("%x\n", Byte); 
      Value = End + 1;
    }
    Buffer = malloc(*Size);
    Value = &PcdList[Index].Value[1];
    for (*Size = 0, Buffer[*Size] = (UINT8) strtoul(Value, &End, 16); Value != End; *Size = *Size + 1, Buffer[*Size] = (UINT8) strtoul(Value, &End, 16)) {
      Value = End + 1;
    }
    return Buffer;
  }
  *Size = 0;
  return 0;
}

VOID
__PcdSetPtr (
  CHAR8   *SkuName             OPTIONAL,
  CHAR8   *DefaultValueName    OPTIONAL,
  CHAR8   *TokenSpaceGuidName,
  CHAR8   *TokenName,
  UINT32  Size,
  UINT8   *Value
  )
{
  int    Index;
  UINT32  ValueIndex;
  
  Index = LookupPcdIndex (SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
  if (Index < 0) {
    fprintf (stderr, "PCD %s.%s.%s.%s is not in database\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
    exit (EXIT_FAILURE);
  }
  switch (PcdList[Index].PcdDataType) {
  case PcdDataTypeBoolean:
  case PcdDataTypeUint8:
  case PcdDataTypeUint16:
  case PcdDataTypeUint32:
  case PcdDataTypeUint64:
    fprintf (stderr, "PCD %s.%s.%s.%s is a value.  Use PcdGet()\n", SkuName, DefaultValueName, TokenSpaceGuidName, TokenName);
    exit (EXIT_FAILURE);
    break;
  case PcdDataTypePointer:
    free(PcdList[Index].Value);
    PcdList[Index].Value = malloc(Size * 5 + 3);
    PcdList[Index].Value[0] = '{';
    for (ValueIndex = 0; ValueIndex < Size; ValueIndex++) {
      printf("Value[%d] = %02x\n", ValueIndex, Value[ValueIndex]);
      sprintf(&PcdList[Index].Value[1 + ValueIndex * 5], "0x%02x,", Value[ValueIndex]);
    }
    PcdList[Index].Value[1 + Size * 5 - 1] = '}';
    PcdList[Index].Value[1 + Size * 5    ] = 0;
    break;
  }
}

VOID
STATIC
ReadInputFile (
  CHAR8   *InputFileName,
  UINT8   **FileBuffer,
  UINT32  *FileSize
  )
{
  FILE    *InputFile;
  UINT32  BytesRead;
  
  //
  // Open Input file and read file data.
  //
  InputFile = fopen (InputFileName, "rb");
  if (InputFile == NULL) {
    fprintf (stderr, "Error opening file %s\n", InputFileName);
    exit (EXIT_FAILURE);
  }
  
  //
  // Go to the end so that we can determine the file size
  //
  if (fseek (InputFile, 0, SEEK_END)) {
    fprintf (stderr, "Error reading input file %s\n", InputFileName);
    fclose (InputFile);
    exit (EXIT_FAILURE);
  }
  
  //
  // Get the file size
  //
  *FileSize = ftell (InputFile);
  if (*FileSize == -1) {
    fprintf (stderr, "Error parsing the input file %s\n", InputFileName);
    fclose (InputFile);
    exit (EXIT_FAILURE);
  }
  
  //
  // Allocate a buffer
  //
  *FileBuffer = malloc (*FileSize);
  if (*FileBuffer == NULL) {
    fprintf (stderr, "Can not allocate buffer for input input file %s\n", InputFileName);
    fclose (InputFile);
    exit (EXIT_FAILURE);
  }
  
  //
  // Reset to the beginning of the file
  //
  if (fseek (InputFile, 0, SEEK_SET)) {
    fprintf (stderr, "Error reading the input file %s\n", InputFileName);
    fclose (InputFile);
    free (*FileBuffer);
    exit (EXIT_FAILURE);
  }

  //
  // Read all of the file contents.
  //
  BytesRead = fread (*FileBuffer, sizeof (UINT8), *FileSize, InputFile);
  if (BytesRead != *FileSize * sizeof (UINT8)) {
    fprintf (stderr, "Error reading the input file %s\n", InputFileName);
    fclose (InputFile);
    free (*FileBuffer);
    exit (EXIT_FAILURE);
  }

  //
  // Close the file
  //
  fclose (InputFile);
}

VOID
STATIC
ParseFile (
  UINT8   *FileBuffer,
  UINT32  FileSize
  )
{
  UINT32  Index;
  UINT32  NumLines;
  UINT32  TokenIndex;
  UINT32  TokenStart;

  for (Index = 0, NumLines = 0; Index < FileSize; Index++) {
    if (FileBuffer[Index] == '\n') {
      NumLines++;
    }
  }
  PcdList = malloc((NumLines + 1) * sizeof(PcdList[0]));
  
  for (Index = 0, TokenIndex = 0, PcdListLength = 0, TokenStart = 0; Index < FileSize; Index++) {
    if (FileBuffer[Index] == ' ') {
      continue;
    }
    if (FileBuffer[Index] == '|' || FileBuffer[Index] == '.' || FileBuffer[Index] == '\n' || FileBuffer[Index] == '\r') {
      RecordToken (FileBuffer, PcdListLength, TokenIndex, TokenStart, Index);
      if (FileBuffer[Index] == '\n' || FileBuffer[Index] == '\r') {
        if (TokenIndex != 0) {
          PcdListLength++;
          TokenIndex = 0;
        }
      } else {
        TokenIndex++;
      }
      TokenStart = Index + 1;
      continue;
    }
  }
  if (Index > TokenStart) {
    RecordToken (FileBuffer, PcdListLength, TokenIndex, TokenStart, Index);
    if (TokenIndex != 0) {
      PcdListLength++;
    }
  }
}

VOID
STATIC
WriteOutputFile (
  CHAR8   *OutputFileName
  )
{
  FILE    *OutputFile;
  UINT32  Index;
  
  //
  // Open output file
  //
  OutputFile = fopen (OutputFileName, "wb");
  if (OutputFile == NULL) {
    fprintf (stderr, "Error opening file %s\n", OutputFileName);
    exit (EXIT_FAILURE);
  }

  for (Index = 0; Index < PcdListLength; Index++) {
    fprintf (
      OutputFile, 
      "%s.%s.%s.%s|%s|%s\n", 
      PcdList[Index].SkuName,
      PcdList[Index].DefaultValueName,
      PcdList[Index].TokenSpaceGuidName,
      PcdList[Index].TokenName,
      PcdList[Index].DataType,
      PcdList[Index].Value
      );
  }

  //
  // Done, write output file.
  //
  if (OutputFile != NULL) {
    fclose (OutputFile);
  }
}

VOID
STATIC
Usage (
  VOID
  )
/*++

Routine Description:

  Displays the utility usage syntax to STDOUT

Arguments:

  None

Returns:

  None

--*/
{
  fprintf (stdout, "Usage: -i <input_file> -o <output_file>\n\n");
  fprintf (stdout, "optional arguments:\n");
  fprintf (stdout, "  -h, --help            Show this help message and exit\n");
  fprintf (stdout, "  -i INPUT_FILENAME, --input INPUT_FILENAME\n\
                        PCD Database Input file name\n");
  fprintf (stdout, "  -o OUTPUT_FILENAME, --output OUTPUT_FILENAME\n\
                        PCD Database Output file name\n");
}

VOID
STATIC
ParseArguments (
  int    argc,
  char   *argv[],
  CHAR8  **InputFileName,
  CHAR8  **OutputFileName
  )
{
  if (argc == 1) {
    fprintf (stderr, "Missing options\n");
    exit (EXIT_FAILURE);
  }

  //
  // Parse command line
  //
  argc--;
  argv++;

  if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {
    Usage ();
    exit (EXIT_SUCCESS);
  }

  while (argc > 0) {
    if ((stricmp (argv[0], "-i") == 0) || (stricmp (argv[0], "--input") == 0)) {
      if (argv[1] == NULL || argv[1][0] == '-') {
        fprintf (stderr, "Invalid option value.  Input File name is missing for -i option\n");
        exit (EXIT_FAILURE);
      }
      *InputFileName = argv[1];
      argc -= 2;
      argv += 2;
      continue; 
    }
    
    if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--output") == 0)) {
      if (argv[1] == NULL || argv[1][0] == '-') {
        fprintf (stderr, "Invalid option value.  Output File name is missing for -i option\n");
        exit (EXIT_FAILURE);
      }
      *OutputFileName = argv[1];
      argc -= 2;
      argv += 2;
      continue; 
    }
    
    if (argv[0][0] == '-') {
      fprintf (stderr, "Unknown option %s\n", argv[0]);
      exit (EXIT_FAILURE);
    }
    argc --;
    argv ++;
  }
  
  //
  // Check Input paramters
  //
  if (*InputFileName == NULL) {
    fprintf (stderr, "Missing option.  Input files is not specified\n");
    exit (EXIT_FAILURE);
  } else {
    printf ("Input file name is %s\n", *InputFileName);
  }

  if (*OutputFileName == NULL) {
    fprintf (stderr, "Missing option.  Output file is not specified\n");
    exit (EXIT_FAILURE);
  } else {
    printf ("Output file name is %s\n", *OutputFileName);
  }
}

int
PcdValueMain (
  int   argc,
  char  *argv[]
  )
{
  CHAR8   *InputFileName;
  CHAR8   *OutputFileName;
  UINT8   *FileBuffer;
  UINT32  FileSize;
  
  printf ("PCD tool start.\n");
  
  //
  //
  //
  ParseArguments (argc, argv, &InputFileName, &OutputFileName);

  //
  // Open Input file and read file data.
  //
  ReadInputFile (InputFileName, &FileBuffer, &FileSize);
  
  //
  //
  //
  ParseFile (FileBuffer, FileSize);
  
  //
  // Customize PCD values in the PCD Database
  //
  PcdEntryPoint ();

  //
  //
  //
  WriteOutputFile (OutputFileName);
  
  printf ("PCD tool done.\n");
  
  exit (EXIT_SUCCESS);
}
