// Copyright 2014 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 language

import (
	"fmt"
	"sort"

	"golang.org/x/text/internal/language"
)

// The Coverage interface is used to define the level of coverage of an
// internationalization service. Note that not all types are supported by all
// services. As lists may be generated on the fly, it is recommended that users
// of a Coverage cache the results.
type Coverage interface {
	// Tags returns the list of supported tags.
	Tags() []Tag

	// BaseLanguages returns the list of supported base languages.
	BaseLanguages() []Base

	// Scripts returns the list of supported scripts.
	Scripts() []Script

	// Regions returns the list of supported regions.
	Regions() []Region
}

var (
	// Supported defines a Coverage that lists all supported subtags. Tags
	// always returns nil.
	Supported Coverage = allSubtags{}
)

// TODO:
// - Support Variants, numbering systems.
// - CLDR coverage levels.
// - Set of common tags defined in this package.

type allSubtags struct{}

// Regions returns the list of supported regions. As all regions are in a
// consecutive range, it simply returns a slice of numbers in increasing order.
// The "undefined" region is not returned.
func (s allSubtags) Regions() []Region {
	reg := make([]Region, language.NumRegions)
	for i := range reg {
		reg[i] = Region{language.Region(i + 1)}
	}
	return reg
}

// Scripts returns the list of supported scripts. As all scripts are in a
// consecutive range, it simply returns a slice of numbers in increasing order.
// The "undefined" script is not returned.
func (s allSubtags) Scripts() []Script {
	scr := make([]Script, language.NumScripts)
	for i := range scr {
		scr[i] = Script{language.Script(i + 1)}
	}
	return scr
}

// BaseLanguages returns the list of all supported base languages. It generates
// the list by traversing the internal structures.
func (s allSubtags) BaseLanguages() []Base {
	bs := language.BaseLanguages()
	base := make([]Base, len(bs))
	for i, b := range bs {
		base[i] = Base{b}
	}
	return base
}

// Tags always returns nil.
func (s allSubtags) Tags() []Tag {
	return nil
}

// coverage is used used by NewCoverage which is used as a convenient way for
// creating Coverage implementations for partially defined data. Very often a
// package will only need to define a subset of slices. coverage provides a
// convenient way to do this. Moreover, packages using NewCoverage, instead of
// their own implementation, will not break if later new slice types are added.
type coverage struct {
	tags    func() []Tag
	bases   func() []Base
	scripts func() []Script
	regions func() []Region
}

func (s *coverage) Tags() []Tag {
	if s.tags == nil {
		return nil
	}
	return s.tags()
}

// bases implements sort.Interface and is used to sort base languages.
type bases []Base

func (b bases) Len() int {
	return len(b)
}

func (b bases) Swap(i, j int) {
	b[i], b[j] = b[j], b[i]
}

func (b bases) Less(i, j int) bool {
	return b[i].langID < b[j].langID
}

// BaseLanguages returns the result from calling s.bases if it is specified or
// otherwise derives the set of supported base languages from tags.
func (s *coverage) BaseLanguages() []Base {
	if s.bases == nil {
		tags := s.Tags()
		if len(tags) == 0 {
			return nil
		}
		a := make([]Base, len(tags))
		for i, t := range tags {
			a[i] = Base{language.Language(t.lang())}
		}
		sort.Sort(bases(a))
		k := 0
		for i := 1; i < len(a); i++ {
			if a[k] != a[i] {
				k++
				a[k] = a[i]
			}
		}
		return a[:k+1]
	}
	return s.bases()
}

func (s *coverage) Scripts() []Script {
	if s.scripts == nil {
		return nil
	}
	return s.scripts()
}

func (s *coverage) Regions() []Region {
	if s.regions == nil {
		return nil
	}
	return s.regions()
}

// NewCoverage returns a Coverage for the given lists. It is typically used by
// packages providing internationalization services to define their level of
// coverage. A list may be of type []T or func() []T, where T is either Tag,
// Base, Script or Region. The returned Coverage derives the value for Bases
// from Tags if no func or slice for []Base is specified. For other unspecified
// types the returned Coverage will return nil for the respective methods.
func NewCoverage(list ...interface{}) Coverage {
	s := &coverage{}
	for _, x := range list {
		switch v := x.(type) {
		case func() []Base:
			s.bases = v
		case func() []Script:
			s.scripts = v
		case func() []Region:
			s.regions = v
		case func() []Tag:
			s.tags = v
		case []Base:
			s.bases = func() []Base { return v }
		case []Script:
			s.scripts = func() []Script { return v }
		case []Region:
			s.regions = func() []Region { return v }
		case []Tag:
			s.tags = func() []Tag { return v }
		default:
			panic(fmt.Sprintf("language: unsupported set type %T", v))
		}
	}
	return s
}
