// Copyright 2013 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 cldr

import (
	"archive/zip"
	"bytes"
	"encoding/xml"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"regexp"
)

// A Decoder loads an archive of CLDR data.
type Decoder struct {
	dirFilter     []string
	sectionFilter []string
	loader        Loader
	cldr          *CLDR
	curLocale     string
}

// SetSectionFilter takes a list top-level LDML element names to which
// evaluation of LDML should be limited.  It automatically calls SetDirFilter.
func (d *Decoder) SetSectionFilter(filter ...string) {
	d.sectionFilter = filter
	// TODO: automatically set dir filter
}

// SetDirFilter limits the loading of LDML XML files of the specied directories.
// Note that sections may be split across directories differently for different CLDR versions.
// For more robust code, use SetSectionFilter.
func (d *Decoder) SetDirFilter(dir ...string) {
	d.dirFilter = dir
}

// A Loader provides access to the files of a CLDR archive.
type Loader interface {
	Len() int
	Path(i int) string
	Reader(i int) (io.ReadCloser, error)
}

var fileRe = regexp.MustCompile(`.*[/\\](.*)[/\\](.*)\.xml`)

// Decode loads and decodes the files represented by l.
func (d *Decoder) Decode(l Loader) (cldr *CLDR, err error) {
	d.cldr = makeCLDR()
	for i := 0; i < l.Len(); i++ {
		fname := l.Path(i)
		if m := fileRe.FindStringSubmatch(fname); m != nil {
			if len(d.dirFilter) > 0 && !in(d.dirFilter, m[1]) {
				continue
			}
			var r io.Reader
			if r, err = l.Reader(i); err == nil {
				err = d.decode(m[1], m[2], r)
			}
			if err != nil {
				return nil, err
			}
		}
	}
	d.cldr.finalize(d.sectionFilter)
	return d.cldr, nil
}

func (d *Decoder) decode(dir, id string, r io.Reader) error {
	var v interface{}
	var l *LDML
	cldr := d.cldr
	switch {
	case dir == "supplemental":
		v = cldr.supp
	case dir == "transforms":
		return nil
	case dir == "bcp47":
		v = cldr.bcp47
	case dir == "validity":
		return nil
	default:
		ok := false
		if v, ok = cldr.locale[id]; !ok {
			l = &LDML{}
			v, cldr.locale[id] = l, l
		}
	}
	x := xml.NewDecoder(r)
	if err := x.Decode(v); err != nil {
		log.Printf("%s/%s: %v", dir, id, err)
		return err
	}
	if l != nil {
		if l.Identity == nil {
			return fmt.Errorf("%s/%s: missing identity element", dir, id)
		}
		// TODO: verify when CLDR bug http://unicode.org/cldr/trac/ticket/8970
		// is resolved.
		// path := strings.Split(id, "_")
		// if lang := l.Identity.Language.Type; lang != path[0] {
		// 	return fmt.Errorf("%s/%s: language was %s; want %s", dir, id, lang, path[0])
		// }
	}
	return nil
}

type pathLoader []string

func makePathLoader(path string) (pl pathLoader, err error) {
	err = filepath.Walk(path, func(path string, _ os.FileInfo, err error) error {
		pl = append(pl, path)
		return err
	})
	return pl, err
}

func (pl pathLoader) Len() int {
	return len(pl)
}

func (pl pathLoader) Path(i int) string {
	return pl[i]
}

func (pl pathLoader) Reader(i int) (io.ReadCloser, error) {
	return os.Open(pl[i])
}

// DecodePath loads CLDR data from the given path.
func (d *Decoder) DecodePath(path string) (cldr *CLDR, err error) {
	loader, err := makePathLoader(path)
	if err != nil {
		return nil, err
	}
	return d.Decode(loader)
}

type zipLoader struct {
	r *zip.Reader
}

func (zl zipLoader) Len() int {
	return len(zl.r.File)
}

func (zl zipLoader) Path(i int) string {
	return zl.r.File[i].Name
}

func (zl zipLoader) Reader(i int) (io.ReadCloser, error) {
	return zl.r.File[i].Open()
}

// DecodeZip loads CLDR data from the zip archive for which r is the source.
func (d *Decoder) DecodeZip(r io.Reader) (cldr *CLDR, err error) {
	buffer, err := ioutil.ReadAll(r)
	if err != nil {
		return nil, err
	}
	archive, err := zip.NewReader(bytes.NewReader(buffer), int64(len(buffer)))
	if err != nil {
		return nil, err
	}
	return d.Decode(zipLoader{archive})
}
