package datokenizer

/**
 * The file reader is basically a port of foma2js,
 * licensed under the Apache License, version 2,
 * and written by Mans Hulden.
 */

import (
	"bufio"
	"compress/gzip"
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"
	"unicode/utf8"
)

const (
	PROPS  = 1
	SIGMA  = 2
	STATES = 3
	NONE   = 4
)

// Special symbols in sigma
var EPSILON, UNKNOWN, IDENTITY, FINAL int

type mapping struct {
	source int
	target int
}

type edge struct {
	in     int
	out    int
	target int
}

type Tokenizer struct {
	sigma       map[rune]int
	sigma_rev   map[int]rune
	arccount    int
	statecount  int
	sigmacount  int
	maxsize     int
	array       []int
	transitions []map[int]*edge
}

func parse_file(file string) *Tokenizer {
	f, err := os.Open(file)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	gz, err := gzip.NewReader(f)
	if err != nil {
		panic(err)
	}
	defer gz.Close()

	return parse(gz)
}

func parse(ior io.Reader) *Tokenizer {
	r := bufio.NewReader(ior)

	tok := &Tokenizer{
		sigma:     make(map[rune]int),
		sigma_rev: make(map[int]rune),
	}

	final := false

	var arrstate, arrin, arrout, arrtarget, arrfinal int

	mode := 0
	var elem []string
	var elemint [5]int

	for {
		line, err := r.ReadString('\n')
		if err != nil {
			if err == io.EOF {
				break
			}
			panic(err)
		}
		if strings.HasPrefix(line, "##foma-net") {
			continue
		}
		if strings.HasPrefix(line, "##props##") {
			mode = PROPS
			continue
		}
		if strings.HasPrefix(line, "##states##") {
			mode = STATES

			// Adds a final transition symbol to sigma
			// written as '#' in Mizobuchi et al (2000)
			tok.sigmacount++
			FINAL = tok.sigmacount
			continue
		}
		if strings.HasPrefix(line, "##sigma##") {
			mode = SIGMA
			continue
		}
		if strings.HasPrefix(line, "##end##") {
			mode = NONE
			continue
		}

		switch mode {
		case PROPS:
			{
				elem = strings.Split(line, " ")
				/*
					fmt.Println("arity:            " + elem[0])
					fmt.Println("arccount:         " + elem[1])
					fmt.Println("statecount:       " + elem[2])
					fmt.Println("linecount:        " + elem[3])
					fmt.Println("finalcount:       " + elem[4])
					fmt.Println("pathcount:        " + elem[5])
					fmt.Println("is_deterministic: " + elem[6])
					fmt.Println("is_pruned:        " + elem[7])
					fmt.Println("is_minimized:     " + elem[8])
					fmt.Println("is_epsilon_free:  " + elem[9])
					fmt.Println("is_loop_free:     " + elem[10])
					fmt.Println("extras:           " + elem[11])
					fmt.Println("name:             " + elem[12])
				*/
				if elem[6] != "1" {
					panic("The FST needs to be deterministic")
				}
				if elem[9] != "1" {
					panic("The FST needs to be epsilon free")
				}

				elemint[0], err = strconv.Atoi(elem[1])
				if err != nil {
					panic("Can't read arccount")
				}
				tok.arccount = elemint[0]

				// States start at 1 in Mizobuchi et al (2000),
				// as the state 0 is associated with a fail.
				// Initialize states and transitions
				elemint[0], err = strconv.Atoi(elem[2])
				if err != nil {
					panic("Can't read statecount")
				}
				tok.statecount = elemint[0]
				tok.transitions = make([]map[int]*edge, elemint[0]+1)
				continue
			}
		case STATES:
			{
				elem = strings.Split(line[0:len(line)-1], " ")
				if elem[0] == "-1" {
					continue
				}
				elemint[0], err = strconv.Atoi(elem[0])

				if len(elem) > 1 {
					elemint[1], err = strconv.Atoi(elem[1])
					if err != nil {
						break
					}
					if len(elem) > 2 {
						elemint[2], err = strconv.Atoi(elem[2])
						if err != nil {
							break
						}
						if len(elem) > 3 {
							elemint[3], err = strconv.Atoi(elem[3])
							if err != nil {
								break
							}
							if len(elem) > 4 {
								elemint[4], err = strconv.Atoi(elem[4])
								if err != nil {
									break
								}
							}
						}
					}
				}

				switch len(elem) {
				case 5:
					{
						arrstate = elemint[0]
						arrin = elemint[1]
						arrout = elemint[2]
						arrtarget = elemint[3]
						arrfinal = elemint[4]
					}
				case 4:
					{
						if elemint[1] == -1 {
							arrstate = elemint[0]
							arrfinal = elemint[3]
						} else {
							arrstate = elemint[0]
							arrin = elemint[1]
							arrtarget = elemint[2]
							arrfinal = elemint[3]
							arrout = arrin
						}
					}
				case 3:
					{
						arrin = elemint[0]
						arrout = elemint[1]
						arrtarget = elemint[2]
					}
				case 2:
					{
						arrin = elemint[0]
						arrtarget = elemint[2]
						arrout = arrin
					}
				}

				// This collects all edges until arrstate changes
				if arrfinal == 1 {
					final = true
				} else {
					final = false
				}

				// While the states in foma start with 0, the states in the
				// Mizobuchi FSA start with one - so we increase every state by 1.

				if arrin != arrout && arrin != EPSILON && tok.sigma_rev[arrin] != '\n' {
					panic("Problem: " + strconv.Itoa(arrstate) + " -> " + strconv.Itoa(arrtarget) + " (" + strconv.Itoa(arrin) + ":" + strconv.Itoa(arrout) + ") ")
				}

				// TODO:
				//   if arrin == EPSILON && arrout == TOKENEND, mark state as newline
				//   if the next transition is the same, remove TOKENEND and add SENTENCEEND
				//   This requires to remove the transition alltogether and marks the state instead.

				// TODO:
				//   if arrout == EPSILON, mark the transition as NOTOKEN

				targetObj := &edge{
					in:     arrin,
					out:    arrout,
					target: arrtarget + 1,
				}

				// Initialize outgoing state
				if tok.transitions[arrstate+1] == nil {
					tok.transitions[arrstate+1] = make(map[int]*edge)
				}

				tok.transitions[arrstate+1][arrin] = targetObj

				if final {
					tok.transitions[arrstate+1][FINAL] = &edge{}
				}

				continue
			}
		case SIGMA:
			{
				elem = strings.SplitN(line[0:len(line)-1], " ", 2)

				// Turn string into sigma id
				number, err := strconv.Atoi(elem[0])

				if err != nil {
					panic(err)
				}

				tok.sigmacount = number

				var symbol rune

				// Read rune
				if utf8.RuneCountInString(elem[1]) == 1 {
					symbol = []rune(elem[1])[0]

					// Probably a MCS
				} else if utf8.RuneCountInString(elem[1]) > 1 {
					switch elem[1] {
					case "@_EPSILON_SYMBOL_@":
						{
							EPSILON = number
							continue
						}
					case "@_UNKNOWN_SYMBOL_@":
						{
							UNKNOWN = number
							continue
						}

					case "@_IDENTITY_SYMBOL_@":
						{
							IDENTITY = number
							continue
						}
					default:
						panic("MCS not supported: " + line)
					}

					// Probably a new line symbol
				} else {
					line, err = r.ReadString('\n')
					if err != nil {
						panic(err)
					}
					if len(line) != 1 {
						panic("MCS not supported:" + line)
					}
					symbol = rune('\n')
				}

				tok.sigma[symbol] = number
				tok.sigma_rev[number] = symbol
			}
		}
	}

	return tok
}

// Implementation of Mizobuchi et al (2000), p.128
func (tok *Tokenizer) buildDA() *Tokenizer {

	mark := 0
	size := 0

	// Create a mapping from s to t
	table := make([]*mapping, tok.arccount+1)

	table[size] = &mapping{source: 1, target: 1}
	size++

	A := make([]int, 0, 256)

	for mark < size {
		s := table[mark].source // This is a state in Ms
		t := table[mark].target // This is a state in Mt
		mark++
		//		fmt.Println("Increase mark", mark)
		// St := append(St, t)
		A = A[:0]
		tok.get_set(s, &A)

		// fmt.Println("Outgoing arcs from t", t, A)

		// tok.array[t].base = tok.x_check(A)
		tok.set_base(t, tok.x_check(A))

		for _, a := range A {

			if a != FINAL {
				s1 := tok.transitions[s][a].target // g(s, a)

				// fmt.Println("Found", s, "to", s1, "via", a)

				t1 := tok.get_base(t) + a
				tok.set_check(t1, t)

				r := in_table(s1, table, size)
				if r == 0 {
					// fmt.Println("Increase size", t1)
					table[size] = &mapping{source: s1, target: t1}
					size++
				} else {
					//fmt.Println("Rep is there", t1, r)
					tok.set_base(t1, -1*r)
					// tok.array[t1].base = -1 * r
				}
			} else {
				fmt.Println("I set a final")
				// t1 := tok.array[t].base + FINAL
				t1 := tok.get_base(t) + FINAL
				// tok.array[t1].check = t
				tok.set_check(t1, t)
			}
		}
	}

	// Following Mizobuchi et al (2000) the size of the
	// FSA should be stored in check(1).
	tok.set_check(1, tok.maxsize+1)
	tok.array = tok.array[:tok.maxsize+1]
	return tok
}

func (tok *Tokenizer) resize(l int) {
	if len(tok.array) < l {
		tok.array = append(tok.array, make([]int, l)...)
	}
}

func (tok *Tokenizer) set_base(p int, v int) {
	l := p*2 + 1
	tok.resize(l)
	if tok.maxsize < l {
		tok.maxsize = l
	}
	tok.array[p*2] = v
}

func (tok *Tokenizer) get_base(p int) int {
	if p*2 >= len(tok.array) {
		return 0
	}
	return tok.array[p*2]
}

func (tok *Tokenizer) set_check(p int, v int) {
	l := p*2 + 1
	tok.resize(l)
	if tok.maxsize < l {
		tok.maxsize = l
	}
	tok.array[(p*2)+1] = v
}

func (tok *Tokenizer) get_check(p int) int {
	if (p*2)+1 >= len(tok.array) {
		return 0
	}
	return tok.array[(p*2)+1]
}

// Check the table if a mapping of s
// exists and return this as a representative
func in_table(s int, table []*mapping, size int) int {
	for x := 0; x < size; x++ {
		if table[x].source == s {
			return table[x].target
		}
	}
	return 0
}

// Set alphabet A to the list of all symbols
// outgoing from s
func (tok *Tokenizer) get_set(s int, A *[]int) {
	for a, _ := range tok.transitions[s] {
		*A = append(*A, a)
	}
}

// Based on Mizobuchi et al (2000), p. 124
// This iterates for every state through the complete double array
// structure until it finds a gap that fits all outgoing transitions
// of the state. This is extremely slow, but is only necessary in the
// construction phase of the tokenizer.
func (tok *Tokenizer) x_check(symbols []int) int {
	// see https://github.com/bramstein/datrie/blob/master/lib/trie.js
	base := 1

	// 	fmt.Println("Resize", len(tok.linarray), "<", ((base + FINAL + 1) * 2))

OVERLAP:
	tok.resize((base + FINAL) * 2)
	for _, a := range symbols {
		// if tok.array[base+a].check != 0 {
		if tok.get_check(base+a) != 0 {
			base++
			goto OVERLAP
		}
	}
	fmt.Println("Found a nice place at", base, "for", len(symbols))
	return base
}

// Based on Mizobuchi et al (2000), p. 129
func (tok *Tokenizer) match(input string) bool {
	t := 1 // Start position
	chars := []rune(input)
	i := 0
	for ; i < len(chars); i++ {
		a := tok.sigma[chars[i]]
		tu := t
		t = tok.get_base(tu) + a
		fmt.Println("Check", a, t, tok.get_check(1))
		if t > tok.get_check(1) {
			break
		} else if tok.get_check(t) != tu {
			break
		} else if tok.get_base(t) < 0 {
			t = -1 * tok.get_base(t)
			// fmt.Println("Match is representative!")
		} else {
			// fmt.Println("Match is fine!")
		}
	}

	if i == len(chars) {
		fmt.Println("At the end")
	} else {
		return false
	}

	// fmt.Println("Hmm...", tok.get_check(tok.get_base(t)+FINAL), "-", t)

	if tok.get_check(tok.get_base(t)+FINAL) == t {
		fmt.Println("FINE")
		return true
	}
	return false
}

// In the final realization, the states can only have 30 bits:
// base[1] -> is final
// base[2] -> is_separate
// check[1] -> translates to epsilon
// check[2] -> appends newine (Maybe)
// If check[1] && check[2] is set, this translates to a sentence split (Maybe)
