// Copyright 2015 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.

package bidi

import (
	"flag"
	"fmt"
	"log"
	"strconv"
	"strings"
	"testing"

	"golang.org/x/text/internal/gen"
	"golang.org/x/text/internal/testtext"
	"golang.org/x/text/internal/ucd"
	"golang.org/x/text/unicode/norm"
)

var testLevels = flag.Bool("levels", false, "enable testing of levels")

// TestBidiCore performs the tests in BidiTest.txt.
// See http://www.unicode.org/Public/UCD/latest/ucd/BidiTest.txt.
func TestBidiCore(t *testing.T) {
	testtext.SkipIfNotLong(t)

	r := gen.OpenUCDFile("BidiTest.txt")
	defer r.Close()

	var wantLevels, wantOrder []string
	p := ucd.New(r, ucd.Part(func(p *ucd.Parser) {
		s := strings.Split(p.String(0), ":")
		switch s[0] {
		case "Levels":
			wantLevels = strings.Fields(s[1])
		case "Reorder":
			wantOrder = strings.Fields(s[1])
		default:
			log.Fatalf("Unknown part %q.", s[0])
		}
	}))

	for p.Next() {
		types := []Class{}
		for _, s := range p.Strings(0) {
			types = append(types, bidiClass[s])
		}
		// We ignore the bracketing part of the algorithm.
		pairTypes := make([]bracketType, len(types))
		pairValues := make([]rune, len(types))

		for i := uint(0); i < 3; i++ {
			if p.Uint(1)&(1<<i) == 0 {
				continue
			}
			lev := level(int(i) - 1)
			par := newParagraph(types, pairTypes, pairValues, lev)

			if *testLevels {
				levels := par.getLevels([]int{len(types)})
				for i, s := range wantLevels {
					if s == "x" {
						continue
					}
					l, _ := strconv.ParseUint(s, 10, 8)
					if level(l)&1 != levels[i]&1 {
						t.Errorf("%s:%d:levels: got %v; want %v", p.String(0), lev, levels, wantLevels)
						break
					}
				}
			}

			order := par.getReordering([]int{len(types)})
			gotOrder := filterOrder(types, order)
			if got, want := fmt.Sprint(gotOrder), fmt.Sprint(wantOrder); got != want {
				t.Errorf("%s:%d:order: got %v; want %v\noriginal %v", p.String(0), lev, got, want, order)
			}
		}
	}
	if err := p.Err(); err != nil {
		log.Fatal(err)
	}
}

var removeClasses = map[Class]bool{
	LRO: true,
	RLO: true,
	RLE: true,
	LRE: true,
	PDF: true,
	BN:  true,
}

// TestBidiCharacters performs the tests in BidiCharacterTest.txt.
// See http://www.unicode.org/Public/UCD/latest/ucd/BidiCharacterTest.txt
func TestBidiCharacters(t *testing.T) {
	testtext.SkipIfNotLong(t)

	ucd.Parse(gen.OpenUCDFile("BidiCharacterTest.txt"), func(p *ucd.Parser) {
		var (
			types      []Class
			pairTypes  []bracketType
			pairValues []rune
			parLevel   level

			wantLevel       = level(p.Int(2))
			wantLevels      = p.Strings(3)
			wantVisualOrder = p.Strings(4)
		)

		switch l := p.Int(1); l {
		case 0, 1:
			parLevel = level(l)
		case 2:
			parLevel = implicitLevel
		default:
			// Spec says to ignore unknown parts.
		}

		runes := p.Runes(0)

		for _, r := range runes {
			// Assign the bracket type.
			if d := norm.NFKD.PropertiesString(string(r)).Decomposition(); d != nil {
				r = []rune(string(d))[0]
			}
			p, _ := LookupRune(r)

			// Assign the class for this rune.
			types = append(types, p.Class())

			switch {
			case !p.IsBracket():
				pairTypes = append(pairTypes, bpNone)
				pairValues = append(pairValues, 0)
			case p.IsOpeningBracket():
				pairTypes = append(pairTypes, bpOpen)
				pairValues = append(pairValues, r)
			default:
				pairTypes = append(pairTypes, bpClose)
				pairValues = append(pairValues, p.reverseBracket(r))
			}
		}
		par := newParagraph(types, pairTypes, pairValues, parLevel)

		// Test results:
		if got := par.embeddingLevel; got != wantLevel {
			t.Errorf("%v:level: got %d; want %d", string(runes), got, wantLevel)
		}

		if *testLevels {
			gotLevels := getLevelStrings(types, par.getLevels([]int{len(types)}))
			if got, want := fmt.Sprint(gotLevels), fmt.Sprint(wantLevels); got != want {
				t.Errorf("%04X %q:%d: got %v; want %v\nval: %x\npair: %v", runes, string(runes), parLevel, got, want, pairValues, pairTypes)
			}
		}

		order := par.getReordering([]int{len(types)})
		order = filterOrder(types, order)
		if got, want := fmt.Sprint(order), fmt.Sprint(wantVisualOrder); got != want {
			t.Errorf("%04X %q:%d: got %v; want %v\ngot order: %s", runes, string(runes), parLevel, got, want, reorder(runes, order))
		}
	})
}

func getLevelStrings(cl []Class, levels []level) []string {
	var results []string
	for i, l := range levels {
		if !removeClasses[cl[i]] {
			results = append(results, fmt.Sprint(l))
		} else {
			results = append(results, "x")
		}
	}
	return results
}

func filterOrder(cl []Class, order []int) []int {
	no := []int{}
	for _, o := range order {
		if !removeClasses[cl[o]] {
			no = append(no, o)
		}
	}
	return no
}

func reorder(r []rune, order []int) string {
	nr := make([]rune, len(order))
	for i, o := range order {
		nr[i] = r[o]
	}
	return string(nr)
}

// bidiClass names and codes taken from class "bc" in
// http://www.unicode.org/Public/8.0.0/ucd/PropertyValueAliases.txt
var bidiClass = map[string]Class{
	"AL":  AL,  // classArabicLetter,
	"AN":  AN,  // classArabicNumber,
	"B":   B,   // classParagraphSeparator,
	"BN":  BN,  // classBoundaryNeutral,
	"CS":  CS,  // classCommonSeparator,
	"EN":  EN,  // classEuropeanNumber,
	"ES":  ES,  // classEuropeanSeparator,
	"ET":  ET,  // classEuropeanTerminator,
	"L":   L,   // classLeftToRight,
	"NSM": NSM, // classNonspacingMark,
	"ON":  ON,  // classOtherNeutral,
	"R":   R,   // classRightToLeft,
	"S":   S,   // classSegmentSeparator,
	"WS":  WS,  // classWhiteSpace,

	"LRO": LRO, // classLeftToRightOverride,
	"RLO": RLO, // classRightToLeftOverride,
	"LRE": LRE, // classLeftToRightEmbedding,
	"RLE": RLE, // classRightToLeftEmbedding,
	"PDF": PDF, // classPopDirectionalFormat,
	"LRI": LRI, // classLeftToRightIsolate,
	"RLI": RLI, // classRightToLeftIsolate,
	"FSI": FSI, // classFirstStrongIsolate,
	"PDI": PDI, // classPopDirectionalIsolate,
}
