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

import (
	"fmt"
	"reflect"
	"strings"
	"testing"
)

func validateConfigAnnotations(configurable jsonConfigurable) (err error) {
	reflectType := reflect.TypeOf(configurable)
	reflectType = reflectType.Elem()
	for i := 0; i < reflectType.NumField(); i++ {
		field := reflectType.Field(i)
		jsonTag := field.Tag.Get("json")
		// Check for mistakes in the json tag
		if jsonTag != "" && !strings.HasPrefix(jsonTag, ",") {
			if !strings.Contains(jsonTag, ",") {
				// Probably an accidental rename, most likely "omitempty" instead of ",omitempty"
				return fmt.Errorf("Field %s.%s has tag %s which specifies to change its json field name to %q.\n"+
					"Did you mean to use an annotation of %q?\n"+
					"(Alternatively, to change the json name of the field, rename the field in source instead.)",
					reflectType.Name(), field.Name, field.Tag, jsonTag, ","+jsonTag)
			} else {
				// Although this rename was probably intentional,
				// a json annotation is still more confusing than renaming the source variable
				requestedName := strings.Split(jsonTag, ",")[0]
				return fmt.Errorf("Field %s.%s has tag %s which specifies to change its json field name to %q.\n"+
					"To change the json name of the field, rename the field in source instead.",
					reflectType.Name(), field.Name, field.Tag, requestedName)

			}
		}
	}
	return nil
}

type configType struct {
	PopulateMe *bool `json:"omitempty"`
}

func (c *configType) SetDefaultConfig() {
}

// tests that ValidateConfigAnnotation works
func TestValidateConfigAnnotations(t *testing.T) {
	config := configType{}
	err := validateConfigAnnotations(&config)
	expectedError := `Field configType.PopulateMe has tag json:"omitempty" which specifies to change its json field name to "omitempty".
Did you mean to use an annotation of ",omitempty"?
(Alternatively, to change the json name of the field, rename the field in source instead.)`
	if err.Error() != expectedError {
		t.Errorf("Incorrect error; expected:\n"+
			"%s\n"+
			"got:\n"+
			"%s",
			expectedError, err.Error())
	}
}

// run validateConfigAnnotations against each type that might have json annotations
func TestProductConfigAnnotations(t *testing.T) {
	err := validateConfigAnnotations(&productVariables{})
	if err != nil {
		t.Errorf(err.Error())
	}
}

func TestMissingVendorConfig(t *testing.T) {
	c := &config{}
	if c.VendorConfig("test").Bool("not_set") {
		t.Errorf("Expected false")
	}
}

func assertStringEquals(t *testing.T, expected, actual string) {
	if actual != expected {
		t.Errorf("expected %q found %q", expected, actual)
	}
}

func TestConfiguredJarList(t *testing.T) {
	list1 := CreateTestConfiguredJarList([]string{"apex1:jarA"})

	t.Run("create", func(t *testing.T) {
		assertStringEquals(t, "apex1:jarA", list1.String())
	})

	list2 := list1.Append("apex2", "jarB")
	t.Run("append", func(t *testing.T) {
		assertStringEquals(t, "apex1:jarA,apex2:jarB", list2.String())
	})

	t.Run("append does not modify", func(t *testing.T) {
		assertStringEquals(t, "apex1:jarA", list1.String())
	})

	// Make sure that two lists created by appending to the same list do not share storage.
	list3 := list1.Append("apex3", "jarC")
	t.Run("append does not share", func(t *testing.T) {
		assertStringEquals(t, "apex1:jarA,apex2:jarB", list2.String())
		assertStringEquals(t, "apex1:jarA,apex3:jarC", list3.String())
	})

	list4 := list3.RemoveList(list1)
	t.Run("remove", func(t *testing.T) {
		assertStringEquals(t, "apex3:jarC", list4.String())
	})

	t.Run("remove does not modify", func(t *testing.T) {
		assertStringEquals(t, "apex1:jarA,apex3:jarC", list3.String())
	})

	// Make sure that two lists created by removing from the same list do not share storage.
	list5 := list3.RemoveList(CreateTestConfiguredJarList([]string{"apex3:jarC"}))
	t.Run("remove", func(t *testing.T) {
		assertStringEquals(t, "apex3:jarC", list4.String())
		assertStringEquals(t, "apex1:jarA", list5.String())
	})
}
