// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Unicode table generator.
// Data read from the web.

package main

import (
	"bufio";
	"flag";
	"fmt";
	"http";
	"log";
	"os";
	"sort";
	"strconv";
	"strings";
	"regexp";
	"unicode";
)

func main() {
	flag.Parse();
	loadChars();	// always needed
	printCategories();
	printScriptOrProperty(false);
	printScriptOrProperty(true);
	printCases();
}

var dataUrl = flag.String("data", "", "full URL for UnicodeData.txt; defaults to --url/UnicodeData.txt");
var url = flag.String("url",
	"http://www.unicode.org/Public/5.1.0/ucd/",
	"URL of Unicode database directory")
var tablelist = flag.String("tables",
	"all",
	"comma-separated list of which tables to generate; can be letter");
var scriptlist = flag.String("scripts",
	"all",
	"comma-separated list of which script tables to generate");
var proplist = flag.String("props",
	"all",
	"comma-separated list of which property tables to generate");
var cases = flag.Bool("cases",
	true,
	"generate case tables");
var test = flag.Bool("test",
	false,
	"test existing tables; can be used to compare web data with package data");
var scriptRe *regexp.Regexp

var die = log.New(os.Stderr, nil, "", log.Lexit|log.Lshortfile);

var category = map[string] bool{ "letter":true }	// Nd Lu etc. letter is a special case

// UnicodeData.txt has form:
//	0037;DIGIT SEVEN;Nd;0;EN;;7;7;7;N;;;;;
//	007A;LATIN SMALL LETTER Z;Ll;0;L;;;;;N;;;005A;;005A
// See http://www.unicode.org/Public/5.1.0/ucd/UCD.html for full explanation
// The fields:
const (
	FCodePoint = iota;
	FName;
	FGeneralCategory;
	FCanonicalCombiningClass;
	FBidiClass;
	FDecompositionType;
	FDecompositionMapping;
	FNumericType;
	FNumericValue;
	FBidiMirrored;
	FUnicode1Name;
	FISOComment;
	FSimpleUppercaseMapping;
	FSimpleLowercaseMapping;
	FSimpleTitlecaseMapping;
	NumField;

	MaxChar = 0x10FFFF;	// anything above this shouldn't exist
)

var fieldName = []string{
	"CodePoint",
	"Name",
	"GeneralCategory",
	"CanonicalCombiningClass",
	"BidiClass",
	"DecompositionType",
	"DecompositionMapping",
	"NumericType",
	"NumericValue",
	"BidiMirrored",
	"Unicode1Name",
	"ISOComment",
	"SimpleUppercaseMapping",
	"SimpleLowercaseMapping",
	"SimpleTitlecaseMapping"
}

// This contains only the properties we're interested in.
type Char struct {
	field	[]string; 	// debugging only; could be deleted if we take out char.dump()
	codePoint	uint32;	// if zero, this index is not a valid code point.
	category	string;
	upperCase	int;
	lowerCase	int;
	titleCase	int;
}

// Scripts.txt has form:
//	A673          ; Cyrillic # Po       SLAVONIC ASTERISK
//	A67C..A67D    ; Cyrillic # Mn   [2] COMBINING CYRILLIC KAVYKA..COMBINING CYRILLIC PAYEROK
// See http://www.unicode.org/Public/5.1.0/ucd/UCD.html for full explanation

type Script struct {
	lo, hi	uint32;	// range of code points
	script	string;
}

var chars = make([]Char, MaxChar+1)
var scripts = make(map[string] []Script)
var props = make(map[string] []Script)	// a property looks like a script; can share the format

var lastChar uint32 = 0

const scriptParseExpression = `([0-9A-F]+)(\.\.[0-9A-F]+)? *; ([A-Za-z_]+)`

// In UnicodeData.txt, some ranges are marked like this:
//	3400;<CJK Ideograph Extension A, First>;Lo;0;L;;;;;N;;;;;
//	4DB5;<CJK Ideograph Extension A, Last>;Lo;0;L;;;;;N;;;;;
// parseCategory returns a state variable indicating the weirdness.
type State int
const (
	SNormal State = iota;	// known to be zero for the type
	SFirst;
	SLast;
	SMissing;
)

func parseCategory(line string) (state State) {
	field := strings.Split(line, ";", -1);
	if len(field) != NumField {
		die.Logf("%5s: %d fields (expected %d)\n", line, len(field), NumField);
	}
	point, err := strconv.Btoui64(field[FCodePoint], 16);
	if err != nil {
		die.Log("%.5s...:", err)
	}
	lastChar = uint32(point);
	if point == 0 {
		return	// not interesting and we use 0 as unset
	}
	if point > MaxChar {
		return;
	}
	char := &chars[point];
	char.field=field;
	if char.codePoint != 0 {
		die.Logf("point U+%04x reused\n");
	}
	char.codePoint = lastChar;
	char.category = field[FGeneralCategory];
	category[char.category] = true;
	switch char.category {
	case "Nd":
		// Decimal digit
		v, err := strconv.Atoi(field[FNumericValue]);
		if err != nil {
			die.Log("U+%04x: bad numeric field: %s", point, err);
		}
	case "Lu":
		char.letter(field[FCodePoint], field[FSimpleLowercaseMapping], field[FSimpleTitlecaseMapping]);
	case "Ll":
		char.letter(field[FSimpleUppercaseMapping], field[FCodePoint], field[FSimpleTitlecaseMapping]);
	case "Lt":
		char.letter(field[FSimpleUppercaseMapping], field[FSimpleLowercaseMapping], field[FCodePoint]);
	case "Lm", "Lo":
		char.letter(field[FSimpleUppercaseMapping], field[FSimpleLowercaseMapping], field[FSimpleTitlecaseMapping]);
	}
	switch {
	case strings.Index(field[FName], ", First>") > 0:
		state = SFirst
	case strings.Index(field[FName], ", Last>") > 0:
		state = SLast
	}
	return
}

func (char *Char) dump(s string) {
	fmt.Print(s, " ");
	for i:=0;i<len(char.field);i++ {
		fmt.Printf("%s:%q ", fieldName[i], char.field[i]);
	}
	fmt.Print("\n");
}

func (char *Char) letter(u, l, t string) {
	char.upperCase = char.letterValue(u, "U");
	char.lowerCase = char.letterValue(l, "L");
	char.titleCase = char.letterValue(t, "T");
}

func (char *Char) letterValue(s string, cas string) int {
	if s == "" {
		return 0
	}
	v, err := strconv.Btoui64(s, 16);
	if err != nil {
		char.dump(cas);
		die.Logf("U+%04x: bad letter(%s): %s", char.codePoint, s, err)
	}
	return int(v)
}

func allCategories() []string {
	a := make([]string, len(category));
	i := 0;
	for k := range category {
		a[i] = k;
		i++;
	}
	return a;
}

func all(scripts map[string] []Script) []string {
	a := make([]string, len(scripts));
	i := 0;
	for k := range scripts {
		a[i] = k;
		i++;
	}
	return a;
}

// Extract the version number from the URL
func version() string {
	// Break on slashes and look for the first numeric field
	fields := strings.Split(*url, "/", 0);
	for _, f := range fields {
		if len(f) > 0 && '0' <= f[0] && f[0] <= '9' {
			return f
		}
	}
	die.Log("unknown version");
	return "Unknown";
}

func letterOp(code int) bool {
	switch chars[code].category {
	case "Lu", "Ll", "Lt", "Lm", "Lo":
		return true
	}
	return false
}

func loadChars() {
	if *dataUrl == "" {
		flag.Set("data", *url + "UnicodeData.txt");
	}
	resp, _, err := http.Get(*dataUrl);
	if err != nil {
		die.Log(err);
	}
	if resp.StatusCode != 200 {
		die.Log("bad GET status for UnicodeData.txt", resp.Status);
	}
	input := bufio.NewReader(resp.Body);
	var first uint32 = 0;
	for {
		line, err := input.ReadString('\n');
		if err != nil {
			if err == os.EOF {
				break;
			}
			die.Log(err);
		}
		switch parseCategory(line[0:len(line)-1]) {
		case SNormal:
			if first != 0 {
				die.Logf("bad state normal at U+%04X", lastChar)
			}
		case SFirst:
			if first != 0 {
				die.Logf("bad state first at U+%04X", lastChar)
			}
			first = lastChar
		case SLast:
			if first == 0 {
				die.Logf("bad state last at U+%04X", lastChar)
			}
			for i := first+1; i <= lastChar; i++ {
				chars[i] = chars[first];
				chars[i].codePoint = i;
			}
			first = 0
		}
	}
	resp.Body.Close();
}

func printCategories() {
	if *tablelist == "" {
		return
	}
	// Find out which categories to dump
	list := strings.Split(*tablelist, ",", 0);
	if *tablelist == "all" {
		list = allCategories()
	}
	if *test {
		fullCategoryTest(list);
		return
	}
	fmt.Printf(
		"// Generated by running\n"
		"//	maketables --tables=%s --data=%s\n"
		"// DO NOT EDIT\n\n"
		"package unicode\n\n",
		*tablelist,
		*dataUrl
	);

	fmt.Println("// Version is the Unicode edition from which the tables are derived.");
	fmt.Printf("const Version = %q\n\n", version());

	if *tablelist == "all" {
		fmt.Println("// Categories is the set of Unicode data tables.");
			fmt.Println("var Categories = map[string] []Range {");
		for k, _ := range category {
			fmt.Printf("\t%q: %s,\n", k, k);
		}
		fmt.Printf("}\n\n");
	}

	decl := make(sort.StringArray, len(list));
	ndecl := 0;
	for _, name := range list {
		if _, ok := category[name]; !ok {
			die.Log("unknown category", name);
		}
		// We generate an UpperCase name to serve as concise documentation and an _UnderScored
		// name to store the data.  This stops godoc dumping all the tables but keeps them
		// available to clients.
		// Cases deserving special comments
		varDecl := "";
		switch name {
		case "letter":
			varDecl = "\tLetter = letter;	// Letter is the set of Unicode letters.\n";
		case "Nd":
			varDecl = "\tDigit = _Nd;	// Digit is the set of Unicode characters with the \"decimal digit\" property.\n";
		case "Lu":
			varDecl = "\tUpper = _Lu;	// Upper is the set of Unicode upper case letters.\n";
		case "Ll":
			varDecl = "\tLower = _Ll;	// Lower is the set of Unicode lower case letters.\n";
		case "Lt":
			varDecl = "\tTitle = _Lt;	// Title is the set of Unicode title case letters.\n";
		}
		if name != "letter" {
			varDecl += fmt.Sprintf(
				"\t%s = _%s;	// %s is the set of Unicode characters in category %s.\n",
				name, name, name, name
			);
		}
		decl[ndecl] = varDecl;
		ndecl++;
		if name == "letter" {	// special case
			dumpRange(
				"var letter = []Range {\n",
				letterOp
			);
			continue;
		}
		dumpRange(
			fmt.Sprintf("var _%s = []Range {\n", name),
			func(code int) bool { return chars[code].category == name }
		);
	}
	decl.Sort();
	fmt.Println("var (");
	for _, d := range decl {
		fmt.Print(d);
	}
	fmt.Println(")\n");
}

type Op func(code int) bool
const format = "\tRange{0x%04x, 0x%04x, %d},\n";

func dumpRange(header string, inCategory Op) {
	fmt.Print(header);
	next := 0;
	// one Range for each iteration
	for {
		// look for start of range
		for next < len(chars) && !inCategory(next) {
			next++
		}
		if next >= len(chars) {
			// no characters remain
			break
		}

		// start of range
		lo := next;
		hi := next;
		stride := 1;
		// accept lo
		next++;
		// look for another character to set the stride
		for next < len(chars) && !inCategory(next) {
			next++
		}
		if next >= len(chars) {
			// no more characters
			fmt.Printf(format, lo, hi, stride);
			break;
		}
		// set stride
		stride = next - lo;
		// check for length of run. next points to first jump in stride
		for i := next; i < len(chars); i++ {
			if inCategory(i) == (((i-lo)%stride) == 0) {
				// accept
				if inCategory(i) {
					hi = i
				}
			} else {
				// no more characters in this run
				break
			}
		}
		fmt.Printf(format, lo, hi, stride);
		// next range: start looking where this range ends
		next = hi + 1;
	}
	fmt.Print("}\n\n");
}

func fullCategoryTest(list []string) {
	for _, name := range list {
		if _, ok := category[name]; !ok {
			die.Log("unknown category", name);
		}
		r, ok := unicode.Categories[name];
		if !ok {
			die.Log("unknown table", name);
		}
		if name == "letter" {
			verifyRange(name, letterOp, r);
		} else {
			verifyRange(
				name,
				func(code int) bool { return chars[code].category == name },
				r
			);
		}
	}
}

func verifyRange(name string, inCategory Op, table []unicode.Range) {
	for i, c := range chars {
		web := inCategory(i);
		pkg := unicode.Is(table, i);
		if web != pkg {
			fmt.Fprintf(os.Stderr, "%s: U+%04X: web=%t pkg=%t\n", name, i, web, pkg);
		}
	}
}

func parseScript(line string, scripts map[string] []Script) {
	comment := strings.Index(line, "#");
	if comment >= 0 {
		line = line[0:comment]
	}
	line = strings.TrimSpace(line);
	if len(line) == 0 {
		return
	}
	field := strings.Split(line, ";", -1);
	if len(field) != 2 {
		die.Logf("%s: %d fields (expected 2)\n", line, len(field));
	}
	matches := scriptRe.MatchStrings(line);
	if len(matches) != 4 {
		die.Logf("%s: %d matches (expected 3)\n", line, len(matches));
	}
	lo, err := strconv.Btoui64(matches[1], 16);
	if err != nil {
		die.Log("%.5s...:", err)
	}
	hi := lo;
	if len(matches[2]) > 2 {	// ignore leading ..
		hi, err = strconv.Btoui64(matches[2][2:len(matches[2])], 16);
		if err != nil {
			die.Log("%.5s...:", err)
		}
	}
	name := matches[3];
	s, ok := scripts[name];
	if len(s) == cap(s) {
		ns := make([]Script, len(s), len(s)+100);
		for i, sc := range s {
			ns[i] = sc
		}
		s = ns;
	}
	s = s[0:len(s)+1];
	s[len(s)-1] = Script{ uint32(lo), uint32(hi), name };
	scripts[name] = s;
}

// The script tables have a lot of adjacent elements. Fold them together.
func foldAdjacent(r []Script) []unicode.Range {
	s := make([]unicode.Range, 0, len(r));
	j := 0;
	for i := 0; i < len(r); i++ {
		if j>0 && int(r[i].lo) == s[j-1].Hi+1 {
			s[j-1].Hi = int(r[i].hi);
		} else {
			s = s[0:j+1];
			s[j] = unicode.Range{int(r[i].lo), int(r[i].hi), 1};
			j++;
		}
	}
	return s;
}

func fullScriptTest(list []string, installed map[string] []unicode.Range, scripts map[string] []Script) {
	for _, name := range list {
		if _, ok := scripts[name]; !ok {
			die.Log("unknown script", name);
		}
		r, ok := installed[name];
		if !ok {
			die.Log("unknown table", name);
		}
		for _, script := range scripts[name] {
			for r := script.lo; r <= script.hi; r++ {
				if !unicode.Is(installed[name], int(r)) {
					fmt.Fprintf(os.Stderr, "U+%04X: not in script %s\n", r, name);
				}
			}
		}
	}
}

// PropList.txt has the same format as Scripts.txt so we can share its parser.
func printScriptOrProperty(doProps bool) {
	flag := "scripts";
	flaglist := *scriptlist;
	file := "Scripts.txt";
	table := scripts;
	installed := unicode.Scripts;
	if doProps {
		flag = "props";
		flaglist = *proplist;
		file = "PropList.txt";
		table = props;
		installed = unicode.Properties;
	}
	if flaglist == "" {
		return
	}
	var err os.Error;
	scriptRe, err = regexp.Compile(scriptParseExpression);
	if err != nil {
		die.Log("re error:", err)
	}
	resp, _, err := http.Get(*url + file);
	if err != nil {
		die.Log(err);
	}
	if resp.StatusCode != 200 {
		die.Log("bad GET status for ", file, ":", resp.Status);
	}
	input := bufio.NewReader(resp.Body);
	for {
		line, err := input.ReadString('\n');
		if err != nil {
			if err == os.EOF {
				break;
			}
			die.Log(err);
		}
		parseScript(line[0:len(line)-1], table);
	}
	resp.Body.Close();

	// Find out which scripts to dump
	list := strings.Split(flaglist, ",", 0);
	if flaglist == "all" {
		list = all(table);
	}
	if *test {
		fullScriptTest(list, installed, table);
		return;
	}

	fmt.Printf(
		"// Generated by running\n"
		"//	maketables --%s=%s --url=%s\n"
		"// DO NOT EDIT\n\n",
		flag,
		flaglist,
		*url
	);
	if flaglist == "all" {
		if doProps {
			fmt.Println("// Properties is the set of Unicode property tables.");
			fmt.Println("var Properties = map[string] []Range {");
		} else {
			fmt.Println("// Scripts is the set of Unicode script tables.");
			fmt.Println("var Scripts = map[string] []Range {");
		}
		for k, _ := range table {
			fmt.Printf("\t%q: %s,\n", k, k);
		}
		fmt.Printf("}\n\n");
	}

	decl := make(sort.StringArray, len(list));
	ndecl := 0;
	for _, name := range list {
		if doProps {
			decl[ndecl] = fmt.Sprintf(
				"\t%s = _%s;\t// %s is the set of Unicode characters with property %s.\n",
				name, name, name, name
			);
		} else {
			decl[ndecl] = fmt.Sprintf(
				"\t%s = _%s;\t// %s is the set of Unicode characters in script %s.\n",
				name, name, name, name
			);
		}
		ndecl++;
		fmt.Printf("var _%s = []Range {\n", name);
		ranges := foldAdjacent(table[name]);
		for _, s := range ranges {
			fmt.Printf(format, s.Lo, s.Hi, s.Stride);
		}
		fmt.Printf("}\n\n");
	}
	decl.Sort();
	fmt.Println("var (");
	for _, d := range decl {
		fmt.Print(d);
	}
	fmt.Println(")\n");
}

const (
	CaseUpper = 1 << iota;
	CaseLower;
	CaseTitle;
	CaseNone = 0;	// must be zero
	CaseMissing = -1;	// character not present; not a valid case state
)

type caseState struct {
	point	int;
	_case	int;
	deltaToUpper	int;
	deltaToLower	int;
	deltaToTitle	int;
}

// Is d a continuation of the state of c?
func (c *caseState) adjacent(d *caseState) bool {
	if d.point < c.point {
		c, d = d, c
	}
	switch {
	case d.point != c.point+1:	// code points not adjacent (shouldn't happen)
		return false
	case d._case != c._case:	// different cases
		return c.upperLowerAdjacent(d);
	case c._case == CaseNone:
		return false
	case c._case == CaseMissing:
		return false
	case d.deltaToUpper != c.deltaToUpper:
		return false
	case d.deltaToLower != c.deltaToLower:
		return false
	case d.deltaToTitle != c.deltaToTitle:
		return false
	}
	return true; 
}

// Is d the same as c, but opposite in upper/lower case? this would make it
// an element of an UpperLower sequence.
func (c *caseState) upperLowerAdjacent(d *caseState) bool {
	// check they're a matched case pair.  we know they have adjacent values
	switch {
	case c._case == CaseUpper && d._case != CaseLower:
		return false
	case c._case == CaseLower && d._case != CaseUpper:
		return false
	}
	// matched pair (at least in upper/lower).  make the order Upper Lower
	if c._case == CaseLower {
		c, d = d, c
	}
	// for an Upper Lower sequence the deltas have to be in order
	//	c: 0 1 0
	//	d: -1 0 -1
	switch {
	case c.deltaToUpper != 0:
		return false
	case c.deltaToLower != 1:
		return false
	case c.deltaToTitle != 0:
		return false
	case d.deltaToUpper != -1:
		return false
	case d.deltaToLower != 0:
		return false
	case d.deltaToTitle != -1:
		return false
	}
	return true
}

// Does this character start an UpperLower sequence?
func (c *caseState) isUpperLower() bool {
	// for an Upper Lower sequence the deltas have to be in order
	//	c: 0 1 0
	switch {
	case c.deltaToUpper != 0:
		return false
	case c.deltaToLower != 1:
		return false
	case c.deltaToTitle != 0:
		return false
	}
	return true
}

// Does this character start a LowerUpper sequence?
func (c *caseState) isLowerUpper() bool {
	// for an Upper Lower sequence the deltas have to be in order
	//	c: -1 0 -1
	switch {
	case c.deltaToUpper != -1:
		return false
	case c.deltaToLower != 0:
		return false
	case c.deltaToTitle != -1:
		return false
	}
	return true
}

func getCaseState(i int) (c *caseState) {
	c = &caseState{ point: i, _case: CaseNone };
	ch := &chars[i];
	switch int(ch.codePoint) {
	case 0:
		c._case = CaseMissing;	// Will get NUL wrong but that doesn't matter
		return;
	case ch.upperCase:
		c._case = CaseUpper;
	case ch.lowerCase:
		c._case = CaseLower;
	case ch.titleCase:
		c._case = CaseTitle;
	}
	if ch.upperCase != 0 {
		c.deltaToUpper = ch.upperCase - i
	}
	if ch.lowerCase != 0 {
		c.deltaToLower = ch.lowerCase - i
	}
	if ch.titleCase != 0 {
		c.deltaToTitle = ch.titleCase - i
	}
	return;
}

func printCases() {
	if !*cases {
		return
	}
	if *test {
		fullCaseTest();
		return
	}
	fmt.Printf(
		"// Generated by running\n"
		"//	maketables --data=%s\n"
		"// DO NOT EDIT\n\n"
		"// CaseRanges is the table describing case mappings for all letters with\n"
		"// non-self mappings.\n"
		"var CaseRanges = _CaseRanges\n"
		"var _CaseRanges = []CaseRange {\n",
		*dataUrl
	);

	var startState *caseState;	// the start of a run; nil for not active
	var prevState = &caseState{};	// the state of the previous character
	for i, c := range chars {
		state := getCaseState(i);
		if state.adjacent(prevState) {
			prevState = state;
			continue;
		}
		// end of run (possibly)
		printCaseRange(startState, prevState);
		startState = nil;
		if state._case != CaseMissing && state._case != CaseNone {
			startState = state;
		}
		prevState = state;
	}
	fmt.Printf("}\n");
}

func printCaseRange(lo, hi *caseState) {
	if lo == nil {
		return
	}
	if lo.deltaToUpper == 0 && lo.deltaToLower == 0 && lo.deltaToTitle == 0 {
		// character represents itself in all cases - no need to mention it
		return
	}
	switch {
	case hi.point > lo.point && lo.isUpperLower():
		fmt.Printf("\tCaseRange{0x%04X, 0x%04X, d{UpperLower, UpperLower, UpperLower}},\n",
			lo.point, hi.point)
	case hi.point > lo.point && lo.isLowerUpper():
		die.Log("LowerUpper sequence: should not happen: U+%04X.  If it's real, need to fix To()", lo.point);
		fmt.Printf("\tCaseRange{0x%04X, 0x%04X, d{LowerUpper, LowerUpper, LowerUpper}},\n",
			lo.point, hi.point)
	default:
		fmt.Printf("\tCaseRange{0x%04X, 0x%04X, d{%d, %d, %d}},\n",
			lo.point, hi.point,
			lo.deltaToUpper, lo.deltaToLower, lo.deltaToTitle)
	}
}

// If the cased value in the Char is 0, it means use the rune itself.
func caseIt(rune, cased int) int {
	if cased == 0 {
		return rune
	}
	return cased
}

func fullCaseTest() {
	for i, c := range chars {
		lower := unicode.ToLower(i);
		want := caseIt(i, c.lowerCase);
		if lower != want {
			fmt.Fprintf(os.Stderr, "lower U+%04X should be U+%04X is U+%04X\n", i, want, lower);
		}
		upper := unicode.ToUpper(i);
		want = caseIt(i, c.upperCase);
		if upper != want {
			fmt.Fprintf(os.Stderr, "upper U+%04X should be U+%04X is U+%04X\n", i, want, upper);
		}
		title := unicode.ToTitle(i);
		want = caseIt(i, c.titleCase);
		if title != want {
			fmt.Fprintf(os.Stderr, "title U+%04X should be U+%04X is U+%04X\n", i, want, title);
		}
	}
}
