#!/usr/bin/perl

use strict;
use warnings;
use IO::Handle;

# Read in from STDIN (I'm lazy) and build a dictionary

# The dictionary. This is a map of first-letters to maps of second-letters to
# arrays of words
my %dict;
# An array of words that are six letters long
my @six;
# An array of words that are seven letters long
my @seven;
# The current line
my $line;
# Word count
my $count = 0;

# Counts of words of various lengths
my @lengths;

# A dictionary of words that have been included (to prevent duplicates)
my %dictionary;
# A dictionary of words to exclude
my %exclude;

sub addWord {
	my $word = shift;
	return 0 if $exclude{$word};
	return 0 if $dictionary{$word};
	$dictionary{$word} = 1;
	my $len = length $word;
	push @six, $word if ($len == 6);
	push @seven, $word if ($len == 7);
	if (defined($lengths[$len])) {
		$lengths[$len]++;
	} else {
		$lengths[$len] = 1;
	}
	$count++;
	my $l = substr $word, 0, 1;
	my $l2 = substr $word, 1, 1;
	my $r = $dict{$l};
	if (!defined($r)) {
		$r = {};
		$dict{$l} = $r;
	}
	my $r2 = $r->{$l2};
	if (!defined($r2)) {
		$r2 = [];
		$r->{$l2} = $r2;
	}
	push @$r2, substr $word, 2;
	return 1;
}

sub printJson {
	my $handle = shift;
	my $obj = shift;
	my $comma = 0;
	if (ref $obj eq "HASH") {
		print $handle "{\n";
		for my $k (keys %$obj) {
			if ($comma) {
				print $handle ",\n";
			} else {
				$comma = 1;
			}
			print $handle '"', $k, '":';
			printJson($handle, $obj->{$k});
		}
		print $handle "}\n";
	} elsif (ref $obj eq "ARRAY") {
		print $handle "[\n";
		for my $o (@$obj) {
			if ($comma) {
				print $handle ",\n";
			} else {
				$comma = 1;
			}
			printJson($handle, $o);
		}
		print $handle "]\n";
	} else {
		print $handle '"', $obj, '"';
	}
}

my $excludeCount = 0;
if (open DICT, "<", "dict.exclude") {
	while ($line = <DICT>) {
		if ($line =~ /^([a-z]{3,7})\r?\n?$/) {
			if (!defined($exclude{$1})) {
				$excludeCount++;
				$exclude{$1} = 1;
			}
		}
	}
	close DICT;
	print "Excluding ", $excludeCount, " words\n";
}

while ($line = <>) {
	if ($line =~ /^([a-z]{3,7})\r?\n?$/) {
		addWord($1);
	}
}

if (open DICT, "<", "dict.include") {	
	while ($line = <DICT>) {
		if ($line =~ /^([a-z]{3,7})\r?\n?$/) {
			addWord($1);
		}
	}
	close DICT;
}

print "Found ", $count, " words:\n";

for (my $i = 0; $i <= $#lengths; $i++) {
	if (defined($lengths[$i])) {
		print "  ", $i, " letters: ", $lengths[$i], "\n";
	}
}

my @time = gmtime(time);

my $version = ($time[5]+1900);
my $t = $time[4] + 1;
$version .= '0' if $t < 10;
$version .= $t;
$t = $time[3];
$version .= '0' if $t < 10;
$version .= $t;
$t = $time[2];
$version .= '0' if $t < 10;
$version .= $t;

print "Writing dictionary version ", $version, "\n";

$dict{"version"} = $version;

my $json;

open $json, ">", "dict.json" or die "Could not open dict.json";

printJson($json, \%dict);

close $json;
