// 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"
	"strings"
)

// 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
	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: use Locale.Parse
		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})
}
