/*
 * Copyright (C) 2002-2014 Free Software Foundation, Inc.
 *
 * This file is part of LIBTASN1.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */


/*****************************************************/
/* File: Test_parser.c                               */
/* Description: Test sequences for these functions:  */
/*     asn1_parser_asn1,                             */
/*****************************************************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "libtasn1.h"

typedef struct
{
  int lineNumber;
  const char *line;
  int errorNumber;
  const char *errorDescription;
} test_type;

const char *fileCorrectName;
char fileErroredName[] = "Test_parser_ERROR.asn";

#define _FILE_ "Test_parser_ERROR.asn"

test_type test_array[] = {
  /* Test DEFINITIONS syntax */
  {5,
   "TEST_PARSER2 { } DEFINITIONS IMPLICIT TAGS ::= BEGIN int1 ::= INTEGER END",
   ASN1_SYNTAX_ERROR,
   _FILE_
   ":6: Error: syntax error, unexpected IDENTIFIER, expecting $end near 'TEST_PARSER'"},
  {6, "TEST_PARSER { }", ASN1_SUCCESS, ""},

  /* Test ASN1_MAX_NAME_SIZE (128) */
  {12,
   "a123456789012345678901234567890123456789012345678901234567890123 ::= INTEGER",
   ASN1_SUCCESS, ""},
  {12,
   "a1234567890123456789012345678901234567890123456789012345678901234 ::= INTEGER",
   ASN1_NAME_TOO_LONG,
   _FILE_ ":12: name too long (more than 64 characters)"},
  /* Test 'check identifier' function */
  {12, "ident1 ::= ident2   ident2 ::= INTEGER",
   ASN1_SUCCESS, ""},
  {12, "ident1 ::= ident2",
   ASN1_IDENTIFIER_NOT_FOUND, _FILE_ ":: identifier 'ident2' not found"},
  {12, "obj1 OBJECT IDENTIFIER ::= {pkix 0 5 4}    "
   "pkix OBJECT IDENTIFIER ::= {1 2}",
   ASN1_SUCCESS, ""},
  {12, "obj1 OBJECT IDENTIFIER ::= {pkix 0 5 4}",
   ASN1_IDENTIFIER_NOT_FOUND, _FILE_ ":: identifier 'pkix' not found"},

  /* Test INTEGER */
  {14, "int1 INTEGER (-5..5),", ASN1_SUCCESS, ""},
  {14, "int1 INTEGER OPTIONAL,", ASN1_SUCCESS, ""},
  {14, "int1 INTEGER DEFAULT 1,", ASN1_SUCCESS, ""},
  {14, "int1 INTEGER DEFAULT -1,", ASN1_SUCCESS, ""},
  {14, "int1 INTEGER DEFAULT v1,", ASN1_SUCCESS, ""},
  {14, "int1 [1] INTEGER,", ASN1_SUCCESS, ""},
  {14, "int1 [1] EXPLICIT INTEGER,", ASN1_SUCCESS, ""},
  {14, "int1 [1] IMPLICIT INTEGER,", ASN1_SUCCESS, ""},
  {12, "Integer ::= [1] EXPLICIT INTEGER {v1(-1), v2(1)}", ASN1_SUCCESS, ""},
  {12, "Integer ::= INTEGER {v1(0), v2}", ASN1_SYNTAX_ERROR,
   _FILE_ ":12: Error: syntax error, unexpected '}', expecting '(' near '}'"},
  {12, "Integer ::= INTEGER {v1(0), 1}",
   ASN1_SYNTAX_ERROR,
   _FILE_
   ":12: Error: syntax error, unexpected NUM, expecting IDENTIFIER or '(' near '1'"},
  {12, "const1 INTEGER ::= -1", ASN1_SUCCESS, ""},
  {12, "const1 INTEGER ::= 1", ASN1_SUCCESS, ""},
  {12, "const1 INTEGER ::= v1",
   ASN1_SYNTAX_ERROR,
   _FILE_
   ":12: Error: syntax error, unexpected IDENTIFIER, expecting NUM or '+' or '-' near 'v1'"},
  {16, " generic generalstring",
   ASN1_IDENTIFIER_NOT_FOUND,
   _FILE_ ":: identifier 'generalstring' not found"},

  /* Test: OID */
  {20, "   oid1    OBJECT IDENTIFIER DEFAULT Oid-type",
   ASN1_IDENTIFIER_NOT_FOUND, _FILE_ ":: identifier 'Oid-type' not found"},
  {20, "   oid1    OBJECT IDENTIFIER DEFAULT 1",
   ASN1_IDENTIFIER_NOT_FOUND, _FILE_ ":: identifier '1' not found"},
  {20, "   oid1    OBJECT IDENTIFIER DEFAULT",
   ASN1_SYNTAX_ERROR,
   _FILE_ ":21: Error: syntax error, unexpected '}' near '}'"},
  {20, "   oid1    OBJECT IDENTIFIER DEFAULT Oid-type1",
   ASN1_SUCCESS, ""},
  {22, "KeyUsage ::= BIT STRING { xxx   (0), enring       UTF8String     (SIZE (1..200)) }",
   ASN1_SYNTAX_ERROR, _FILE_":22: Error: syntax error, unexpected UTF8String, expecting '(' near 'UTF8String'"},

  /* end */
  {0}
};

static int
readLine (FILE * file, char *line)
{
  int c;

  while (((c = fgetc (file)) != EOF) && (c != '\n'))
    {
      *line = c;
      line++;
    }

  *line = 0;

  return c;
}

static void
createFile (int lineNumber, const char *line)
{
  FILE *fileIn, *fileOut;
  char lineRead[1024];
  int fileInLineNumber = 0;

  fileIn = fopen (fileCorrectName, "r");
  fileOut = fopen (fileErroredName, "w");

  while (readLine (fileIn, lineRead) != EOF)
    {
      fileInLineNumber++;
      if (fileInLineNumber == lineNumber)
	fprintf (fileOut, "%s\n", line);
      else
	fprintf (fileOut, "%s\n", lineRead);
    }

  fclose (fileOut);
  fclose (fileIn);
}


int
main (int argc, char *argv[])
{
  int result;
  asn1_node definitions = NULL;
  char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
  test_type *test;
  int errorCounter = 0, testCounter = 0;
  int verbose = 0;

  if (argc > 1)
    verbose = 1;

  fileCorrectName = getenv ("ASN1PARSER");
  if (!fileCorrectName)
    fileCorrectName = "Test_parser.asn";

  if (verbose != 0)
    {
      printf ("\n\n/****************************************/\n");
      printf ("/*     Test sequence : Test_parser      */\n");
      printf ("/****************************************/\n\n");
      printf ("ASN1PARSER: %s\n", fileCorrectName);
    }

  result = asn1_parser2tree (fileCorrectName, &definitions, errorDescription);

  if (result != ASN1_SUCCESS)
    {
      printf ("File '%s' not correct\n", fileCorrectName);
      asn1_perror (result);
      printf ("ErrorDescription = %s\n\n", errorDescription);
      exit (1);
    }

  /* Only for Test */
  /* asn1_visit_tree(stdout,definitions,"TEST_PARSER",ASN1_PRINT_ALL); */

  /* Clear the definitions structures */
  asn1_delete_structure (&definitions);


  test = test_array;

  while (test->lineNumber != 0)
    {
      testCounter++;

      createFile (test->lineNumber, test->line);

      result =
	asn1_parser2tree (fileErroredName, &definitions, errorDescription);
      asn1_delete_structure (&definitions);

      if ((result != test->errorNumber) ||
	  (strcmp (errorDescription, test->errorDescription)))
	{
	  errorCounter++;
	  printf ("ERROR N. %d:\n", errorCounter);
	  printf ("  Line %d - %s\n", test->lineNumber, test->line);
	  printf ("  Error expected: %s - %s\n",
		  asn1_strerror (test->errorNumber), test->errorDescription);
	  printf ("  Error detected: %s - %s\n\n", asn1_strerror (result),
		  errorDescription);
	  exit (1);
	}

      test++;
    }


  if (verbose != 0)
    {
      printf ("Total tests : %d\n", testCounter);
      printf ("Total errors: %d\n", errorCounter);
    }

  if (errorCounter > 0)
    return 1;

  exit (0);
}
