package g

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
)

const (
	DEF_LANG     = "en"
	DEF_LANG_EXT = ".json"
)

var (
	defaultLang *Lang

	ErrLangNoExists = errors.New("language path not exists")
)

func SetDefaultLang(l *Lang) {
	defaultLang = l
}

type Lang struct {
	baseDir string                       // lang file base dir
	words   map[string]map[string]string // single lang words
}

func NewLang(dir string) *Lang {
	l := &Lang{
		baseDir: dir,
		words:   make(map[string]map[string]string),
	}

	l.Reload()

	return l
}

func (self *Lang) Get(k string, useLang ...string) string {
	l := DEF_LANG
	if len(useLang) > 0 {
		l = useLang[0]
	}
	kv, ok := self.words[l]
	if !ok {
		fmt.Println("no language:", l)
		return ""
	}
	if word, ok := kv[k]; ok {
		return word
	}
	fmt.Printf("no key<%v> for lang<%v>\n", k, l)
	return ""
}

func (self *Lang) Reload() {
	self.scan(filepath.Join(self.baseDir))
}

func (self *Lang) scan(jsDir string) {
	self.words = make(map[string]map[string]string)

	err := filepath.Walk(jsDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if info.IsDir() {
			self.words[info.Name()] = make(map[string]string)
		}
		if filepath.Ext(path) != DEF_LANG_EXT {
			return nil
		}
		langDir := filepath.Base(filepath.Dir(path))
		langKv, ok := self.words[langDir]
		if !ok {
			return ErrLangNoExists
		}

		fh, err := os.Open(path)
		if err != nil {
			return err
		}
		defer fh.Close()

		data, err := ioutil.ReadAll(fh)
		if err != nil {
			return err
		}
		partial := map[string]string{}
		err = json.Unmarshal(data, &partial)
		if err != nil {
			return err
		}

		for k, v := range partial {
			langKv[k] = v
		}

		return nil
	})

	if err != nil {
		fmt.Println("scan() error:", err)
	}
}

func T(k string, useLang ...string) string {
	if defaultLang != nil {
		return defaultLang.Get(k, useLang...)
	}
	return ""
}
