/*******************************************************************************************************************
*	FUNCTION NAME : main.c
*
*	DESCRIPTON : calls other functions
*
*	RETURN VALUE : SUCCESS
*
***********************************************************************************************************************/
int main(int argc, char *argv[])
{
	/*error handling for command line arguments*/
	if(NULL == argv[1])
	{
		printf("please provide first input file name\n");
		exit(FAILURE);
	}
	if(NULL == argv[2])
	{
		printf("please provide second input file name\n");
		exit(FAILURE);
	}
	if(NULL == argv[3])
	{
		printf("please provide output file name\n");
		exit(FAILURE);
	}

	FILE *fp1;//file pointer for first input file
	FILE *fp2;//file pointer for second input file
	FILE *fp3;//file pointer for output file

	char input[MAX];//for storing strings read from the file
	memset(input, 0, MAX*sizeof(char));//initializing input to null

	char keyword[10];//for storing keywors read from the file
	memset(keyword, 0, 10*sizeof(char));//initializing keyword to null

	node *start = NULL;//start pointer for the list

	file_open(&fp1, argv[1], "r"); //open first input file for reading
	file_open(&fp2, argv[2], "r"); //open second input file for reading
	file_open(&fp3, argv[3], "w"); //open output file for writing

	/*reading from input1.txt and storing it into the linked list*/
	while(1)
	{
		fgets(input, (MAX-1)*sizeof(char), fp1); //using fgets to read full line
		if(feof(fp1))
		{
			break;
		}
		remove_new_line(input);
		insert_list(&start, input);
	}

	printf("\n*************LIST CONTENTS***************\n");
	display_list(&start); //display the linked list

	/*reading the keyword from input2.txt, searching in linked list and if found printing it in output.txt*/
	while(1)
	{
		/*use only fscanf to read the keyword, else you won't get the correct output*/
		fscanf(fp2, "%s", keyword); 
		if(feof(fp2))
		{
			break;
		}
		search_keyword(&start, keyword, &fp3);
	}
	
	/*closing all input files*/
	file_close(&fp1);
	file_close(&fp2);
	file_close(&fp3);

	/*free the linked list*/
	free_list(&start);

	return SUCCESS;
}
void populate_device_details(DeviceDetails* deviceDetail, char* filePtr)
{
  FILE *fp=NULL;
  char line[1024];
  const char sep[2] = "=";
  char *token;

  if(deviceDetail){
    //if deviceInfo.txt file present - read data from it
    if(filePtr) {
      fp = fopen(filePtr, "r+");
      if(fp){
        while(fgets(line, sizeof line, fp)!= NULL) {
          //printf("#### line = %s \n", line);
          token = strtok(line, sep);
          //printf("#### token1 = %s \n", token);
          if(!strcmp("manufacturingId", token)){
              token = strtok(NULL, sep);
              //printf("#### token2 = %s \n", token);
              deviceDetail->manufacturingId = strdup(token);
              remove_new_line(deviceDetail->manufacturingId);
          } else if(!strcmp("deviceType", token)){
              token = strtok(NULL, sep);
              //printf("#### token2 = %s \n", token);
              deviceDetail->deviceType = strdup(token);
              remove_new_line(deviceDetail->deviceType);
          } else if(!strcmp("deviceMake", token)){
              token = strtok(NULL, sep);
              //printf("#### token2 = %s \n", token);
              deviceDetail->deviceMake = strdup(token);
              remove_new_line(deviceDetail->deviceMake);
          } else if(!strcmp("deviceModel", token)){
              token = strtok(NULL, sep);
              //printf("#### token2 = %s \n", token);
              deviceDetail->deviceModel = strdup(token);
              remove_new_line(deviceDetail->deviceModel);
          } else if(!strcmp("deviceFirmwareVer", token)){
              token = strtok(NULL, sep);
              //printf("#### token2 = %s \n", token);
              deviceDetail->deviceFirmwareVer = strdup(token);
              remove_new_line(deviceDetail->deviceFirmwareVer);
          } else if(!strcmp("hardwareVer", token)){
              token = strtok(NULL, sep);
              //printf("#### token2 = %s \n", token);
              deviceDetail->hardwareVer = strdup(token);
              remove_new_line(deviceDetail->hardwareVer);
          } else if(!strcmp("macAddress", token)){
              token = strtok(NULL, sep);
              //printf("#### token2 = %s \n", token);
              deviceDetail->macAddress = strdup(token);
              remove_new_line(deviceDetail->macAddress);
          } else if(!strcmp("deviceSerialNum", token)){
              token = strtok(NULL, sep);
              //printf("#### token2 = %s \n", token);
              deviceDetail->deviceSerialNum = strdup(token);
              remove_new_line(deviceDetail->deviceSerialNum);
          } else if(!strcmp("ipv4", token)){
              token = strtok(NULL, sep);
              //printf("#### token2 = %s \n", token);
              deviceDetail->ipv4 = strdup(token);
              remove_new_line(deviceDetail->ipv4);
          }
        }
      }
    } else {
      deviceDetail->manufacturingId = strdup("FTX1942802A");
      deviceDetail->deviceType = strdup("Industrial Integrated Router");
      deviceDetail->deviceMake = strdup("Cisco Systems Inc.");
      deviceDetail->deviceModel = strdup("IR-829-GW");
      deviceDetail->deviceFirmwareVer = strdup("v1.3");
      deviceDetail->hardwareVer = strdup("v0.7");
      deviceDetail->macAddress = getMacAddress();
      deviceDetail->deviceSerialNum = strdup("FTX1942802A");
      deviceDetail->ipv4 = getipv4_Address() ;
      //deviceDetail->ipv4 = strdup("10.194.30.234") ;
    }
  }
  return;
}
void PerformTasks::summarize_outputs(const C_arg& c_inst_args, C_time& c_inst_time) {
    std::ofstream& f_log = Log::get_stream();
    //--------------------------------------------------
    // stdout
    //--------------------------------------------------
    std::cout << "Running Time" << std::endl;
    std::cout << "     Parsing arguments" << std::endl;
    std::cout << "          Start:" << remove_new_line(c_inst_time.start_parse_args) << std::endl;
    std::cout << "          End  :" << remove_new_line(c_inst_time.end_parse_args) << std::endl;

    std::cout << "     Checking reads" << std::endl;
    for (std::size_t it = 0; it < c_inst_args.read_files_names.size(); ++it) {
        std::cout << "          " << c_inst_args.read_files_names[it] << std::endl;
        std::cout << "               Start:" << remove_new_line(c_inst_time.vector_start_check_read_file[it]) << std::endl;
        std::cout << "               End  :" << remove_new_line(c_inst_time.vector_end_check_read_file[it]) << std::endl;
    }

    std::cout << "     Correcting errors in reads" << std::endl;
    for (std::size_t it = 0; it < c_inst_args.read_files_names.size(); ++it) {
        std::cout << "          " << c_inst_args.read_files_names[it] << std::endl;
        std::cout << "               Start:" << remove_new_line(c_inst_time.vector_start_correct_errors_in_reads[it]) << std::endl;
        std::cout << "               End  :" << remove_new_line(c_inst_time.vector_end_correct_errors_in_reads[it]) << std::endl;
    }

    if (c_inst_args.nowrite == false) {
        std::cout << "     Writing corrected reads" << std::endl;
        for (std::size_t it = 0; it < c_inst_args.read_files_names.size(); ++it) {
            std::cout << "          " << c_inst_args.read_files_names[it] << std::endl;
            std::cout << "               Start:" << remove_new_line(c_inst_time.vector_start_write_corrected_reads[it]) << std::endl;
            std::cout << "               End  :" << remove_new_line(c_inst_time.vector_end_write_corrected_reads[it]) << std::endl;
        }
    }

    std::cout << std::endl;
    std::cout << "The program is successfully completed" << std::endl << std::endl;

    //--------------------------------------------------
    // log file
    //--------------------------------------------------
    f_log << "Running Time" << std::endl;
    f_log << "     Parsing arguments" << std::endl;
    f_log << "          Start:" << remove_new_line(c_inst_time.start_parse_args) << std::endl;
    f_log << "          End  :" << remove_new_line(c_inst_time.end_parse_args) << std::endl;

    f_log << "     Checking reads" << std::endl;
    for (std::size_t it = 0; it < c_inst_args.read_files_names.size(); ++it) {
        f_log << "          " << c_inst_args.read_files_names[it] << std::endl;
        f_log << "               Start:" << remove_new_line(c_inst_time.vector_start_check_read_file[it]) << std::endl;
        f_log << "               End  :" << remove_new_line(c_inst_time.vector_end_check_read_file[it]) << std::endl;
    }

    f_log << "     Correcting errors in reads" << std::endl;
    for (std::size_t it = 0; it < c_inst_args.read_files_names.size(); ++it) {
        f_log << "          " << c_inst_args.read_files_names[it] << std::endl;
        f_log << "               Start:" << remove_new_line(c_inst_time.vector_start_correct_errors_in_reads[it]) << std::endl;
        f_log << "               End  :" << remove_new_line(c_inst_time.vector_end_correct_errors_in_reads[it]) << std::endl;
    }

    if (c_inst_args.nowrite == false) {
        f_log << "     Writing corrected reads" << std::endl;
        for (std::size_t it = 0; it < c_inst_args.read_files_names.size(); ++it) {
            f_log << "          " << c_inst_args.read_files_names[it] << std::endl;
            f_log << "               Start:" << remove_new_line(c_inst_time.vector_start_write_corrected_reads[it]) << std::endl;
            f_log << "               End  :" << remove_new_line(c_inst_time.vector_end_write_corrected_reads[it]) << std::endl;
        }
    }

    f_log << std::endl;
    f_log << "The program is successfully completed" << std::endl << std::endl;
}