#!/usr/bin/perl

package main;

use 5.006_000;
use diagnostics;
use strict;
use warnings;

sub escape($)
{
	my ($value) = @_;
	
	# if line contains a comma or " we have to quote the contents
	if ($value =~ /[",]/)
	{
		# escape " characters by replacing each with two " characters
		$value =~ s/"/""/g;
		$value = '"' . $value . '"';
	}

	return $value;
}

sub parse($$)
{
	my ($in_file_name, $out_file_name) = @_;

	my $records_hash_ref = {};
	my $record_ref = undef;

	my $line_count = 0;
	my $record_count = 0;
	
	# read the records from the output file in our custom format
	open(FH_IN, "< $in_file_name") or die "Couldn't read file '$in_file_name': $!\n";
	my $line;
	while (defined($line = <FH_IN>))
	{
		$line_count++;
		chomp $line;
		
		if ($line =~ /^\s*$/)
		{
			# blank line
		}
		else
		{	
			# extract data from line by removing leading and trailing spaces and looking for "field: value"
			$line =~ s/^\s+//;
			$line =~ s/\s+$//;
			if ($line =~ /^(\w+):\s*(.*)$/)
			{
				my $field = $1;
				my $value = $2;
				
				if (($field ne 'Name') && (!defined($record_ref)))
				{
					print("WARNING: must specify a name before using any other field in input file, line #$line_count: '$line'.\n");
				}
				elsif ($field eq 'Name')
				{
					$record_ref = $records_hash_ref->{$value};
					if (!defined($record_ref))
					{
						$record_count++;
						$record_ref = {};
						$record_ref->{'Name'} = $value;
						$records_hash_ref->{$value} = $record_ref;
					}
					else
					{
						print("WARNING: duplicate record name '$value' in input file line #$line_count: '$line'.\n");
					}
				}
				elsif (($field eq 'Email') || ($field eq 'Address') || ($field eq 'Completed_the_Test'))
				{
					# Set the field of the current record to the specified value
					if (!defined($record_ref->{$field}))
					{
						$record_ref->{$field} = $value;
					}
					else
					{
						print("WARNING: redefined field '$field' in input file line #$line_count: '$line'.\n");
					}
				}
				else
				{
					print("WARNING: unrecognized field '$field' in input file line #$line_count: '$line'.\n");
				}
			}
			else
			{
				print("WARNING: unparsed input file line #$line_count: '$line'.\n");
			}
		}
	}
	close(FH_IN);
	print("$record_count records loaded from $line_count lines in '$in_file_name'.\n");
	
	# write the records to the output file in CSV format
	open(FH_OUT, "> $out_file_name") or die "Couldn't write file '$out_file_name': $!\n";
	foreach my $name (sort keys %{$records_hash_ref}) 
	{
		$record_ref = $records_hash_ref->{$name};
		my $first = 1;
		foreach my $field ('Name', 'Email', 'Address', 'Completed_the_Test')
		{
			if ($first)
			{
				$first = 0;
			}
			else
			{
				print FH_OUT ",";
			}
			print FH_OUT escape($record_ref->{$field});
		}
		print FH_OUT "\n";
	}
	close(FH_OUT);
	print("$record_count records written as $record_count CSV lines to '$out_file_name'.\n");
}

parse("test_records.txt", "test_records.csv");