// Copyright 2017 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 androidmk

import (
	"fmt"
	"strings"

	mkparser "android/soong/androidmk/parser"

	bpparser "github.com/google/blueprint/parser"
)

func stringToStringValue(s string) bpparser.Expression {
	return &bpparser.String{
		Value: s,
	}
}

func stringListToStringValueList(list []string) []bpparser.Expression {
	valList := make([]bpparser.Expression, len(list))
	for i, l := range list {
		valList[i] = stringToStringValue(l)
	}
	return valList
}

func addValues(val1, val2 bpparser.Expression) (bpparser.Expression, error) {
	if val1 == nil {
		return val2, nil
	}

	if val1.Type() == bpparser.StringType && val2.Type() == bpparser.ListType {
		val1 = &bpparser.List{
			Values: []bpparser.Expression{val1},
		}
	} else if val2.Type() == bpparser.StringType && val1.Type() == bpparser.ListType {
		val2 = &bpparser.List{
			Values: []bpparser.Expression{val1},
		}
	} else if val1.Type() != val2.Type() {
		return nil, fmt.Errorf("cannot add mismatched types")
	}

	return &bpparser.Operator{
		Operator: '+',
		Args:     [2]bpparser.Expression{val1, val2},
	}, nil
}

func makeToStringExpression(ms *mkparser.MakeString, file *bpFile) (bpparser.Expression, error) {
	var val bpparser.Expression
	var err error

	if ms.Strings[0] != "" {
		val = stringToStringValue(ms.Strings[0])
	}

	for i, s := range ms.Strings[1:] {
		if ret, ok := ms.Variables[i].EvalFunction(file.scope); ok {
			if len(ret) > 1 {
				return nil, fmt.Errorf("Unexpected list value %s", ms.Dump())
			}
			val, err = addValues(val, stringToStringValue(ret[0]))
		} else {
			name, err := extractVariableName(ms.Variables[i].Name, file)
			if err != nil {
				return nil, err
			}
			tmp := &bpparser.Variable{
				Name:  name,
				Value: &bpparser.String{},
			}

			if tmp.Name == "TOP" {
				if s[0] == '/' {
					s = s[1:]
				} else {
					s = "." + s
				}
			} else {
				val, err = addValues(val, tmp)
				if err != nil {
					return nil, err
				}
			}
		}

		if s != "" {
			tmp := stringToStringValue(s)
			val, err = addValues(val, tmp)
			if err != nil {
				return nil, err
			}
		}
	}

	return val, nil
}

func stringToListValue(s string) bpparser.Expression {
	list := strings.Fields(s)
	valList := make([]bpparser.Expression, len(list))
	for i, l := range list {
		valList[i] = &bpparser.String{
			Value: l,
		}
	}
	return &bpparser.List{
		Values: valList,
	}

}

func makeToListExpression(ms *mkparser.MakeString, file *bpFile) (bpparser.Expression, error) {
	fields := ms.Split(" \t")

	var listOfListValues []bpparser.Expression

	listValue := &bpparser.List{}

	for _, f := range fields {
		if len(f.Variables) == 1 && f.Strings[0] == "" && f.Strings[1] == "" {
			if ret, ok := f.Variables[0].EvalFunction(file.scope); ok {
				listValue.Values = append(listValue.Values, stringListToStringValueList(ret)...)
			} else {
				name, err := extractVariableName(f.Variables[0].Name, file)
				if err != nil {
					return nil, err
				}
				if name == "TOP" {
					listValue.Values = append(listValue.Values, &bpparser.String{
						Value: ".",
					})
				} else {
					if len(listValue.Values) > 0 {
						listOfListValues = append(listOfListValues, listValue)
					}
					listOfListValues = append(listOfListValues, &bpparser.Variable{
						Name:  name,
						Value: &bpparser.List{},
					})
					listValue = &bpparser.List{}
				}
			}
		} else {
			s, err := makeToStringExpression(f, file)
			if err != nil {
				return nil, err
			}
			if s == nil {
				continue
			}

			listValue.Values = append(listValue.Values, s)
		}
	}

	if len(listValue.Values) > 0 {
		listOfListValues = append(listOfListValues, listValue)
	}

	if len(listOfListValues) == 0 {
		return listValue, nil
	}

	val := listOfListValues[0]
	for _, tmp := range listOfListValues[1:] {
		var err error
		val, err = addValues(val, tmp)
		if err != nil {
			return nil, err
		}
	}

	return val, nil
}

func stringToBoolValue(s string) (bpparser.Expression, error) {
	var b bool
	s = strings.TrimSpace(s)
	switch s {
	case "true":
		b = true
	case "false", "":
		b = false
	case "-frtti": // HACK for LOCAL_RTTI_VALUE
		b = true
	default:
		return nil, fmt.Errorf("unexpected bool value %s", s)
	}
	return &bpparser.Bool{
		Value: b,
	}, nil
}

func makeToBoolExpression(ms *mkparser.MakeString, file *bpFile) (bpparser.Expression, error) {
	if !ms.Const() {
		if len(ms.Variables) == 1 && ms.Strings[0] == "" && ms.Strings[1] == "" {
			name, err := extractVariableName(ms.Variables[0].Name, file)
			if err != nil {
				return nil, err
			}
			return &bpparser.Variable{
				Name:  name,
				Value: &bpparser.Bool{},
			}, nil
		} else {
			return nil, fmt.Errorf("non-const bool expression %s", ms.Dump())
		}
	}

	return stringToBoolValue(ms.Value(nil))
}

func extractVariableName(name *mkparser.MakeString, file *bpFile) (string, error) {
	if !name.Const() {
		return "", fmt.Errorf("Unsupported non-const variable name %s", name.Dump())
	}

	variableName := name.Value(nil)

	if newName, ok := file.variableRenames[variableName]; ok {
		variableName = newName
	}

	return variableName, nil
}
