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

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

const eof = -1

var (
	defaultEscaper = strings.NewReplacer(
		"\n", "$\n")
	inputEscaper = strings.NewReplacer(
		"\n", "$\n",
		" ", "$ ")
	outputEscaper = strings.NewReplacer(
		"\n", "$\n",
		" ", "$ ",
		":", "$:")
)

// ninjaString contains the parsed result of a string that can contain references to variables (e.g. $cflags) that will
// be propagated to the build.ninja file.  For literal strings with no variable references, the variables field will be
// nil. For strings with variable references str contains the original, unparsed string, and variables contains a
// pointer to a list of references, each with a span of bytes they should replace and a Variable interface.
type ninjaString struct {
	str       string
	variables *[]variableReference
}

// variableReference contains information about a single reference to a variable (e.g. $cflags) inside a parsed
// ninjaString.  start and end are int32 to reduce memory usage.  A nil variable is a special case of an inserted '$'
// at the beginning of the string to handle leading whitespace that must not be stripped by ninja.
type variableReference struct {
	// start is the offset of the '$' character from the beginning of the unparsed string.
	start int32

	// end is the offset of the character _after_ the final character of the variable name (or '}' if using the
	//'${}'  syntax)
	end int32

	variable Variable
}

type scope interface {
	LookupVariable(name string) (Variable, error)
	IsRuleVisible(rule Rule) bool
	IsPoolVisible(pool Pool) bool
}

func simpleNinjaString(str string) *ninjaString {
	return &ninjaString{str: str}
}

type parseState struct {
	scope        scope
	str          string
	varStart     int
	varNameStart int
	result       *ninjaString
}

func (ps *parseState) pushVariable(start, end int, v Variable) {
	if ps.result.variables == nil {
		ps.result.variables = &[]variableReference{{start: int32(start), end: int32(end), variable: v}}
	} else {
		*ps.result.variables = append(*ps.result.variables, variableReference{start: int32(start), end: int32(end), variable: v})
	}
}

type stateFunc func(*parseState, int, rune) (stateFunc, error)

// parseNinjaString parses an unescaped ninja string (i.e. all $<something>
// occurrences are expected to be variables or $$) and returns a list of the
// variable names that the string references.
func parseNinjaString(scope scope, str string) (*ninjaString, error) {
	// naively pre-allocate slice by counting $ signs
	n := strings.Count(str, "$")
	if n == 0 {
		if len(str) > 0 && str[0] == ' ' {
			str = "$" + str
		}
		return simpleNinjaString(str), nil
	}
	variableReferences := make([]variableReference, 0, n)
	result := &ninjaString{
		str:       str,
		variables: &variableReferences,
	}

	parseState := &parseState{
		scope:  scope,
		str:    str,
		result: result,
	}

	state := parseFirstRuneState
	var err error
	for i := 0; i < len(str); i++ {
		r := rune(str[i])
		state, err = state(parseState, i, r)
		if err != nil {
			return nil, fmt.Errorf("error parsing ninja string %q: %s", str, err)
		}
	}

	_, err = state(parseState, len(parseState.str), eof)
	if err != nil {
		return nil, err
	}

	// All the '$' characters counted initially could have been "$$" escapes, leaving no
	// variable references.  Deallocate the variables slice if so.
	if len(*result.variables) == 0 {
		result.variables = nil
	}

	return result, nil
}

func parseFirstRuneState(state *parseState, i int, r rune) (stateFunc, error) {
	if r == ' ' {
		state.pushVariable(0, 1, nil)
	}
	return parseStringState(state, i, r)
}

func parseStringState(state *parseState, i int, r rune) (stateFunc, error) {
	switch {
	case r == '$':
		state.varStart = i
		return parseDollarStartState, nil

	case r == eof:
		return nil, nil

	default:
		return parseStringState, nil
	}
}

func parseDollarStartState(state *parseState, i int, r rune) (stateFunc, error) {
	switch {
	case r >= 'a' && r <= 'z', r >= 'A' && r <= 'Z',
		r >= '0' && r <= '9', r == '_', r == '-':
		// The beginning of a of the variable name.
		state.varNameStart = i
		return parseDollarState, nil

	case r == '$':
		// Just a "$$".  Go back to parseStringState.
		return parseStringState, nil

	case r == '{':
		// This is a bracketted variable name (e.g. "${blah.blah}").
		state.varNameStart = i + 1
		return parseBracketsState, nil

	case r == eof:
		return nil, fmt.Errorf("unexpected end of string after '$'")

	default:
		// This was some arbitrary character following a dollar sign,
		// which is not allowed.
		return nil, fmt.Errorf("invalid character after '$' at byte "+
			"offset %d", i)
	}
}

func parseDollarState(state *parseState, i int, r rune) (stateFunc, error) {
	switch {
	case r >= 'a' && r <= 'z', r >= 'A' && r <= 'Z',
		r >= '0' && r <= '9', r == '_', r == '-':
		// A part of the variable name.  Keep going.
		return parseDollarState, nil
	}

	// The variable name has ended, output what we have.
	v, err := state.scope.LookupVariable(state.str[state.varNameStart:i])
	if err != nil {
		return nil, err
	}

	state.pushVariable(state.varStart, i, v)

	switch {
	case r == '$':
		// A dollar after the variable name (e.g. "$blah$").  Start a new one.
		state.varStart = i
		return parseDollarStartState, nil

	case r == eof:
		return nil, nil

	default:
		return parseStringState, nil
	}
}

func parseBracketsState(state *parseState, i int, r rune) (stateFunc, error) {
	switch {
	case r >= 'a' && r <= 'z', r >= 'A' && r <= 'Z',
		r >= '0' && r <= '9', r == '_', r == '-', r == '.':
		// A part of the variable name.  Keep going.
		return parseBracketsState, nil

	case r == '}':
		if state.varNameStart == i {
			// The brackets were immediately closed.  That's no good.
			return nil, fmt.Errorf("empty variable name at byte offset %d",
				i)
		}

		// This is the end of the variable name.
		v, err := state.scope.LookupVariable(state.str[state.varNameStart:i])
		if err != nil {
			return nil, err
		}

		state.pushVariable(state.varStart, i+1, v)
		return parseStringState, nil

	case r == eof:
		return nil, fmt.Errorf("unexpected end of string in variable name")

	default:
		// This character isn't allowed in a variable name.
		return nil, fmt.Errorf("invalid character in variable name at "+
			"byte offset %d", i)
	}
}

func parseNinjaStrings(scope scope, strs []string) ([]*ninjaString,
	error) {

	if len(strs) == 0 {
		return nil, nil
	}
	result := make([]*ninjaString, len(strs))
	for i, str := range strs {
		ninjaStr, err := parseNinjaString(scope, str)
		if err != nil {
			return nil, fmt.Errorf("error parsing element %d: %s", i, err)
		}
		result[i] = ninjaStr
	}
	return result, nil
}

func (n *ninjaString) Value(pkgNames map[*packageContext]string) string {
	if n.variables == nil || len(*n.variables) == 0 {
		return defaultEscaper.Replace(n.str)
	}
	str := &strings.Builder{}
	n.ValueWithEscaper(str, pkgNames, defaultEscaper)
	return str.String()
}

func (n *ninjaString) ValueWithEscaper(w io.StringWriter, pkgNames map[*packageContext]string,
	escaper *strings.Replacer) {

	if n.variables == nil || len(*n.variables) == 0 {
		w.WriteString(escaper.Replace(n.str))
		return
	}

	i := 0
	for _, v := range *n.variables {
		w.WriteString(escaper.Replace(n.str[i:v.start]))
		if v.variable == nil {
			w.WriteString("$ ")
		} else {
			w.WriteString("${")
			w.WriteString(v.variable.fullName(pkgNames))
			w.WriteString("}")
		}
		i = int(v.end)
	}
	w.WriteString(escaper.Replace(n.str[i:len(n.str)]))
}

func (n *ninjaString) Eval(variables map[Variable]*ninjaString) (string, error) {
	if n.variables == nil || len(*n.variables) == 0 {
		return n.str, nil
	}

	w := &strings.Builder{}
	i := 0
	for _, v := range *n.variables {
		w.WriteString(n.str[i:v.start])
		if v.variable == nil {
			w.WriteString(" ")
		} else {
			variable, ok := variables[v.variable]
			if !ok {
				return "", fmt.Errorf("no such global variable: %s", v.variable)
			}
			value, err := variable.Eval(variables)
			if err != nil {
				return "", err
			}
			w.WriteString(value)
		}
		i = int(v.end)
	}
	w.WriteString(n.str[i:len(n.str)])
	return w.String(), nil
}

func (n *ninjaString) Variables() []Variable {
	if n.variables == nil || len(*n.variables) == 0 {
		return nil
	}

	variables := make([]Variable, 0, len(*n.variables))
	for _, v := range *n.variables {
		if v.variable != nil {
			variables = append(variables, v.variable)
		}
	}
	return variables
}

func validateNinjaName(name string) error {
	for i, r := range name {
		valid := (r >= 'a' && r <= 'z') ||
			(r >= 'A' && r <= 'Z') ||
			(r >= '0' && r <= '9') ||
			(r == '_') ||
			(r == '-') ||
			(r == '.')
		if !valid {

			return fmt.Errorf("%q contains an invalid Ninja name character "+
				"%q at byte offset %d", name, r, i)
		}
	}
	return nil
}

func toNinjaName(name string) string {
	ret := bytes.Buffer{}
	ret.Grow(len(name))
	for _, r := range name {
		valid := (r >= 'a' && r <= 'z') ||
			(r >= 'A' && r <= 'Z') ||
			(r >= '0' && r <= '9') ||
			(r == '_') ||
			(r == '-') ||
			(r == '.')
		if valid {
			ret.WriteRune(r)
		} else {
			// TODO(jeffrygaston): do escaping so that toNinjaName won't ever output duplicate
			// names for two different input names
			ret.WriteRune('_')
		}
	}

	return ret.String()
}

var builtinRuleArgs = []string{"out", "in"}

func validateArgName(argName string) error {
	err := validateNinjaName(argName)
	if err != nil {
		return err
	}

	// We only allow globals within the rule's package to be used as rule
	// arguments.  A global in another package can always be mirrored into
	// the rule's package by defining a new variable, so this doesn't limit
	// what's possible.  This limitation prevents situations where a Build
	// invocation in another package must use the rule-defining package's
	// import name for a 3rd package in order to set the rule's arguments.
	if strings.ContainsRune(argName, '.') {
		return fmt.Errorf("%q contains a '.' character", argName)
	}

	if argName == "tags" {
		return fmt.Errorf("\"tags\" is a reserved argument name")
	}

	for _, builtin := range builtinRuleArgs {
		if argName == builtin {
			return fmt.Errorf("%q conflicts with Ninja built-in", argName)
		}
	}

	return nil
}

func validateArgNames(argNames []string) error {
	for _, argName := range argNames {
		err := validateArgName(argName)
		if err != nil {
			return err
		}
	}

	return nil
}
