// 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 currency

import (
	"fmt"
	"io"
	"sort"

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

// Amount is an amount-currency unit pair.
type Amount struct {
	amount   interface{} // Change to decimal(64|128).
	currency Unit
}

// Currency reports the currency unit of this amount.
func (a Amount) Currency() Unit { return a.currency }

// TODO: based on decimal type, but may make sense to customize a bit.
// func (a Amount) Decimal()
// func (a Amount) Int() (int64, error)
// func (a Amount) Fraction() (int64, error)
// func (a Amount) Rat() *big.Rat
// func (a Amount) Float() (float64, error)
// func (a Amount) Scale() uint
// func (a Amount) Precision() uint
// func (a Amount) Sign() int
//
// Add/Sub/Div/Mul/Round.

var space = []byte(" ")

// Format implements fmt.Formatter. It accepts format.State for
// language-specific rendering.
func (a Amount) Format(s fmt.State, verb rune) {
	v := formattedValue{
		currency: a.currency,
		amount:   a.amount,
		format:   defaultFormat,
	}
	v.Format(s, verb)
}

// formattedValue is currency amount or unit that implements language-sensitive
// formatting.
type formattedValue struct {
	currency Unit
	amount   interface{} // Amount, Unit, or number.
	format   *options
}

// Format implements fmt.Formatter. It accepts format.State for
// language-specific rendering.
func (v formattedValue) Format(s fmt.State, verb rune) {
	var lang compact.ID
	if state, ok := s.(format.State); ok {
		lang, _ = compact.RegionalID(compact.Tag(state.Language()))
	}

	// Get the options. Use DefaultFormat if not present.
	opt := v.format
	if opt == nil {
		opt = defaultFormat
	}
	cur := v.currency
	if cur.index == 0 {
		cur = opt.currency
	}

	// TODO: use pattern.
	io.WriteString(s, opt.symbol(lang, cur))
	if v.amount != nil {
		s.Write(space)

		// TODO: apply currency-specific rounding
		scale, _ := opt.kind.Rounding(cur)
		if _, ok := s.Precision(); !ok {
			fmt.Fprintf(s, "%.*f", scale, v.amount)
		} else {
			fmt.Fprint(s, v.amount)
		}
	}
}

// Formatter decorates a given number, Unit or Amount with formatting options.
type Formatter func(amount interface{}) formattedValue

// func (f Formatter) Options(opts ...Option) Formatter

// TODO: call this a Formatter or FormatFunc?

var dummy = USD.Amount(0)

// adjust creates a new Formatter based on the adjustments of fn on f.
func (f Formatter) adjust(fn func(*options)) Formatter {
	var o options = *(f(dummy).format)
	fn(&o)
	return o.format
}

// Default creates a new Formatter that defaults to currency unit c if a numeric
// value is passed that is not associated with a currency.
func (f Formatter) Default(currency Unit) Formatter {
	return f.adjust(func(o *options) { o.currency = currency })
}

// Kind sets the kind of the underlying currency unit.
func (f Formatter) Kind(k Kind) Formatter {
	return f.adjust(func(o *options) { o.kind = k })
}

var defaultFormat *options = ISO(dummy).format

var (
	// Uses Narrow symbols. Overrides Symbol, if present.
	NarrowSymbol Formatter = Formatter(formNarrow)

	// Use Symbols instead of ISO codes, when available.
	Symbol Formatter = Formatter(formSymbol)

	// Use ISO code as symbol.
	ISO Formatter = Formatter(formISO)

	// TODO:
	// // Use full name as symbol.
	// Name Formatter
)

// options configures rendering and rounding options for an Amount.
type options struct {
	currency Unit
	kind     Kind

	symbol func(compactIndex compact.ID, c Unit) string
}

func (o *options) format(amount interface{}) formattedValue {
	v := formattedValue{format: o}
	switch x := amount.(type) {
	case Amount:
		v.amount = x.amount
		v.currency = x.currency
	case *Amount:
		v.amount = x.amount
		v.currency = x.currency
	case Unit:
		v.currency = x
	case *Unit:
		v.currency = *x
	default:
		if o.currency.index == 0 {
			panic("cannot format number without a currency being set")
		}
		// TODO: Must be a number.
		v.amount = x
		v.currency = o.currency
	}
	return v
}

var (
	optISO    = options{symbol: lookupISO}
	optSymbol = options{symbol: lookupSymbol}
	optNarrow = options{symbol: lookupNarrow}
)

// These need to be functions, rather than curried methods, as curried methods
// are evaluated at init time, causing tables to be included unconditionally.
func formISO(x interface{}) formattedValue    { return optISO.format(x) }
func formSymbol(x interface{}) formattedValue { return optSymbol.format(x) }
func formNarrow(x interface{}) formattedValue { return optNarrow.format(x) }

func lookupISO(x compact.ID, c Unit) string    { return c.String() }
func lookupSymbol(x compact.ID, c Unit) string { return normalSymbol.lookup(x, c) }
func lookupNarrow(x compact.ID, c Unit) string { return narrowSymbol.lookup(x, c) }

type symbolIndex struct {
	index []uint16 // position corresponds with compact index of language.
	data  []curToIndex
}

var (
	normalSymbol = symbolIndex{normalLangIndex, normalSymIndex}
	narrowSymbol = symbolIndex{narrowLangIndex, narrowSymIndex}
)

func (x *symbolIndex) lookup(lang compact.ID, c Unit) string {
	for {
		index := x.data[x.index[lang]:x.index[lang+1]]
		i := sort.Search(len(index), func(i int) bool {
			return index[i].cur >= c.index
		})
		if i < len(index) && index[i].cur == c.index {
			x := index[i].idx
			start := x + 1
			end := start + uint16(symbols[x])
			if start == end {
				return c.String()
			}
			return symbols[start:end]
		}
		if lang == 0 {
			break
		}
		lang = lang.Parent()
	}
	return c.String()
}
