// Copyright 2015 Google Inc. All rights reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package kati

import (
	"bytes"
	"fmt"
	"io"
)

type Var interface {
	Value
	Append(*Evaluator, string) Var
	AppendVar(*Evaluator, Value) Var
	Flavor() string
	Origin() string
	IsDefined() bool
}

type TargetSpecificVar struct {
	v  Var
	op string
}

func (v *TargetSpecificVar) Append(ev *Evaluator, s string) Var {
	return &TargetSpecificVar{
		v:  v.v.Append(ev, s),
		op: v.op,
	}
}
func (v *TargetSpecificVar) AppendVar(ev *Evaluator, v2 Value) Var {
	return &TargetSpecificVar{
		v:  v.v.AppendVar(ev, v2),
		op: v.op,
	}
}
func (v *TargetSpecificVar) Flavor() string {
	return v.v.Flavor()
}
func (v *TargetSpecificVar) Origin() string {
	return v.v.Origin()
}
func (v *TargetSpecificVar) IsDefined() bool {
	return v.v.IsDefined()
}
func (v *TargetSpecificVar) String() string {
	// TODO: If we add the info of |op| a test starts
	// failing. Shouldn't we use this only for debugging?
	return v.v.String()
	// return v.v.String() + " (op=" + v.op + ")"
}
func (v *TargetSpecificVar) Eval(w io.Writer, ev *Evaluator) {
	v.v.Eval(w, ev)
}

func (v *TargetSpecificVar) Serialize() SerializableVar {
	return SerializableVar{
		Type:     v.op,
		Children: []SerializableVar{v.v.Serialize()},
	}
}

func (v *TargetSpecificVar) Dump(w io.Writer) {
	dumpByte(w, valueTypeTSV)
	dumpString(w, v.op)
	v.v.Dump(w)
}

type SimpleVar struct {
	value  string
	origin string
}

func (v *SimpleVar) Flavor() string  { return "simple" }
func (v *SimpleVar) Origin() string  { return v.origin }
func (v *SimpleVar) IsDefined() bool { return true }

func (v *SimpleVar) String() string { return v.value }
func (v *SimpleVar) Eval(w io.Writer, ev *Evaluator) {
	io.WriteString(w, v.value)
}
func (v *SimpleVar) Serialize() SerializableVar {
	return SerializableVar{
		Type:   "simple",
		V:      v.value,
		Origin: v.origin,
	}
}
func (v *SimpleVar) Dump(w io.Writer) {
	dumpByte(w, valueTypeSimple)
	dumpString(w, v.value)
	dumpString(w, v.origin)
}

func (v *SimpleVar) Append(ev *Evaluator, s string) Var {
	val, _, err := parseExpr([]byte(s), nil, false)
	if err != nil {
		panic(err)
	}
	abuf := newBuf()
	io.WriteString(abuf, v.value)
	writeByte(abuf, ' ')
	val.Eval(abuf, ev)
	v.value = abuf.String()
	freeBuf(abuf)
	return v
}

func (v *SimpleVar) AppendVar(ev *Evaluator, val Value) Var {
	abuf := newBuf()
	io.WriteString(abuf, v.value)
	writeByte(abuf, ' ')
	val.Eval(abuf, ev)
	v.value = abuf.String()
	freeBuf(abuf)
	return v
}

type AutomaticVar struct {
	value []byte
}

func (v *AutomaticVar) Flavor() string  { return "simple" }
func (v *AutomaticVar) Origin() string  { return "automatic" }
func (v *AutomaticVar) IsDefined() bool { return true }

func (v *AutomaticVar) String() string { return string(v.value) }
func (v *AutomaticVar) Eval(w io.Writer, ev *Evaluator) {
	w.Write(v.value)
}
func (v *AutomaticVar) Serialize() SerializableVar {
	panic(fmt.Sprintf("cannnot serialize automatic var:%s", v.value))
}
func (v *AutomaticVar) Dump(w io.Writer) {
	panic(fmt.Sprintf("cannnot dump automatic var:%s", v.value))
}

func (v *AutomaticVar) Append(ev *Evaluator, s string) Var {
	val, _, err := parseExpr([]byte(s), nil, false)
	if err != nil {
		panic(err)
	}
	buf := bytes.NewBuffer(v.value)
	buf.WriteByte(' ')
	val.Eval(buf, ev)
	v.value = buf.Bytes()
	return v
}

func (v *AutomaticVar) AppendVar(ev *Evaluator, val Value) Var {
	buf := bytes.NewBuffer(v.value)
	buf.WriteByte(' ')
	val.Eval(buf, ev)
	v.value = buf.Bytes()
	return v
}

type RecursiveVar struct {
	expr   Value
	origin string
}

func (v *RecursiveVar) Flavor() string  { return "recursive" }
func (v *RecursiveVar) Origin() string  { return v.origin }
func (v *RecursiveVar) IsDefined() bool { return true }

func (v *RecursiveVar) String() string { return v.expr.String() }
func (v *RecursiveVar) Eval(w io.Writer, ev *Evaluator) {
	v.expr.Eval(w, ev)
}
func (v *RecursiveVar) Serialize() SerializableVar {
	return SerializableVar{
		Type:     "recursive",
		Children: []SerializableVar{v.expr.Serialize()},
		Origin:   v.origin,
	}
}
func (v *RecursiveVar) Dump(w io.Writer) {
	dumpByte(w, valueTypeRecursive)
	v.expr.Dump(w)
	dumpString(w, v.origin)
}

func (v *RecursiveVar) Append(_ *Evaluator, s string) Var {
	var expr Expr
	if e, ok := v.expr.(Expr); ok {
		expr = append(e, literal(" "))
	} else {
		expr = Expr{v.expr, literal(" ")}
	}
	sv, _, err := parseExpr([]byte(s), nil, true)
	if err != nil {
		panic(err)
	}
	if aexpr, ok := sv.(Expr); ok {
		expr = append(expr, aexpr...)
	} else {
		expr = append(expr, sv)
	}
	v.expr = expr
	return v
}

func (v *RecursiveVar) AppendVar(ev *Evaluator, val Value) Var {
	var buf bytes.Buffer
	buf.WriteString(v.expr.String())
	buf.WriteByte(' ')
	buf.WriteString(val.String())
	e, _, err := parseExpr(buf.Bytes(), nil, true)
	if err != nil {
		panic(err)
	}
	v.expr = e
	return v
}

type UndefinedVar struct{}

func (UndefinedVar) Flavor() string  { return "undefined" }
func (UndefinedVar) Origin() string  { return "undefined" }
func (UndefinedVar) IsDefined() bool { return false }
func (UndefinedVar) String() string  { return "" }
func (UndefinedVar) Eval(_ io.Writer, _ *Evaluator) {
}
func (UndefinedVar) Serialize() SerializableVar {
	return SerializableVar{Type: "undefined"}
}
func (UndefinedVar) Dump(w io.Writer) {
	dumpByte(w, valueTypeUndefined)
}

func (UndefinedVar) Append(*Evaluator, string) Var {
	return UndefinedVar{}
}

func (UndefinedVar) AppendVar(_ *Evaluator, val Value) Var {
	return UndefinedVar{}
}

type Vars map[string]Var

func (vt Vars) Lookup(name string) Var {
	if v, ok := vt[name]; ok {
		return v
	}
	return UndefinedVar{}
}

func (vt Vars) Assign(name string, v Var) {
	switch v.Origin() {
	case "override", "environment override":
	default:
		if ov, ok := vt[name]; ok {
			if ov.Origin() == "command line" {
				return
			}
		}
	}
	vt[name] = v
}

func NewVars(vt Vars) Vars {
	r := make(Vars)
	r.Merge(vt)
	return r
}

func (vt Vars) Merge(vt2 Vars) {
	for k, v := range vt2 {
		vt[k] = v
	}
}

// save saves value of the variable named name.
// calling returned value will restore to the old value at the time
// when save called.
func (vt Vars) save(name string) func() {
	if v, ok := vt[name]; ok {
		return func() {
			vt[name] = v
		}
	}
	return func() {
		delete(vt, name)
	}
}
