// Copyright 2020 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 bp2build

import (
	"io/ioutil"
	"os"
	"strings"
	"testing"

	"android/soong/android"
)

func setUp() {
	var err error
	buildDir, err = ioutil.TempDir("", "bazel_queryview_test")
	if err != nil {
		panic(err)
	}
}

func tearDown() {
	os.RemoveAll(buildDir)
}

func TestMain(m *testing.M) {
	run := func() int {
		setUp()
		defer tearDown()

		return m.Run()
	}

	os.Exit(run())
}

func TestGenerateModuleRuleShims(t *testing.T) {
	moduleTypeFactories := map[string]android.ModuleFactory{
		"custom":          customModuleFactoryBase,
		"custom_test":     customTestModuleFactoryBase,
		"custom_defaults": customDefaultsModuleFactoryBasic,
	}
	ruleShims := CreateRuleShims(moduleTypeFactories)

	if len(ruleShims) != 1 {
		t.Errorf("Expected to generate 1 rule shim, but got %d", len(ruleShims))
	}

	ruleShim := ruleShims["bp2build"]
	expectedRules := []string{
		"custom",
		"custom_defaults",
		"custom_test_",
	}

	if len(ruleShim.rules) != len(expectedRules) {
		t.Errorf("Expected %d rules, but got %d", len(expectedRules), len(ruleShim.rules))
	}

	for i, rule := range ruleShim.rules {
		if rule != expectedRules[i] {
			t.Errorf("Expected rule shim to contain %s, but got %s", expectedRules[i], rule)
		}
	}
	expectedBzl := `load("//build/bazel/queryview_rules:providers.bzl", "SoongModuleInfo")

def _custom_impl(ctx):
    return [SoongModuleInfo()]

custom = rule(
    implementation = _custom_impl,
    attrs = {
        "soong_module_name": attr.string(mandatory = True),
        "soong_module_variant": attr.string(),
        "soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
        "api": attr.string(),
        "arch_paths": attr.string_list(),
        "arch_paths_exclude": attr.string_list(),
        # bazel_module start
#         "label": attr.string(),
#         "bp2build_available": attr.bool(),
        # bazel_module end
        "bool_prop": attr.bool(),
        "bool_ptr_prop": attr.bool(),
        "dir": attr.string(),
        "does_not_convert_to_bazel": attr.bool(),
        "embedded_prop": attr.string(),
        "int64_ptr_prop": attr.int(),
        # nested_props start
#         "nested_prop": attr.string(),
        # nested_props end
        # nested_props_ptr start
#         "nested_prop": attr.string(),
        # nested_props_ptr end
        "one_to_many_prop": attr.bool(),
        "other_embedded_prop": attr.string(),
        "string_list_prop": attr.string_list(),
        "string_literal_prop": attr.string(),
        "string_prop": attr.string(),
        "string_ptr_prop": attr.string(),
        "test_config_setting": attr.bool(),
    },
)

def _custom_defaults_impl(ctx):
    return [SoongModuleInfo()]

custom_defaults = rule(
    implementation = _custom_defaults_impl,
    attrs = {
        "soong_module_name": attr.string(mandatory = True),
        "soong_module_variant": attr.string(),
        "soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
        "api": attr.string(),
        "arch_paths": attr.string_list(),
        "arch_paths_exclude": attr.string_list(),
        "bool_prop": attr.bool(),
        "bool_ptr_prop": attr.bool(),
        "dir": attr.string(),
        "does_not_convert_to_bazel": attr.bool(),
        "embedded_prop": attr.string(),
        "int64_ptr_prop": attr.int(),
        # nested_props start
#         "nested_prop": attr.string(),
        # nested_props end
        # nested_props_ptr start
#         "nested_prop": attr.string(),
        # nested_props_ptr end
        "one_to_many_prop": attr.bool(),
        "other_embedded_prop": attr.string(),
        "string_list_prop": attr.string_list(),
        "string_literal_prop": attr.string(),
        "string_prop": attr.string(),
        "string_ptr_prop": attr.string(),
        "test_config_setting": attr.bool(),
    },
)

def _custom_test__impl(ctx):
    return [SoongModuleInfo()]

custom_test_ = rule(
    implementation = _custom_test__impl,
    attrs = {
        "soong_module_name": attr.string(mandatory = True),
        "soong_module_variant": attr.string(),
        "soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
        "api": attr.string(),
        "arch_paths": attr.string_list(),
        "arch_paths_exclude": attr.string_list(),
        "bool_prop": attr.bool(),
        "bool_ptr_prop": attr.bool(),
        "dir": attr.string(),
        "does_not_convert_to_bazel": attr.bool(),
        "embedded_prop": attr.string(),
        "int64_ptr_prop": attr.int(),
        # nested_props start
#         "nested_prop": attr.string(),
        # nested_props end
        # nested_props_ptr start
#         "nested_prop": attr.string(),
        # nested_props_ptr end
        "one_to_many_prop": attr.bool(),
        "other_embedded_prop": attr.string(),
        "string_list_prop": attr.string_list(),
        "string_literal_prop": attr.string(),
        "string_prop": attr.string(),
        "string_ptr_prop": attr.string(),
        "test_config_setting": attr.bool(),
        # test_prop start
#         "test_string_prop": attr.string(),
        # test_prop end
    },
)
`

	if ruleShim.content != expectedBzl {
		t.Errorf(
			"Expected the generated rule shim bzl to be:\n%s\nbut got:\n%s",
			expectedBzl,
			ruleShim.content)
	}
}

func TestGenerateSoongModuleBzl(t *testing.T) {
	ruleShims := map[string]RuleShim{
		"file1": RuleShim{
			rules:   []string{"a", "b"},
			content: "irrelevant",
		},
		"file2": RuleShim{
			rules:   []string{"c", "d"},
			content: "irrelevant",
		},
	}
	files := CreateBazelFiles(ruleShims, make(map[string]BazelTargets), QueryView)

	var actualSoongModuleBzl BazelFile
	for _, f := range files {
		if f.Basename == "soong_module.bzl" {
			actualSoongModuleBzl = f
		}
	}

	expectedLoad := `load("//build/bazel/queryview_rules:file1.bzl", "a", "b")
load("//build/bazel/queryview_rules:file2.bzl", "c", "d")
`
	expectedRuleMap := `soong_module_rule_map = {
    "a": a,
    "b": b,
    "c": c,
    "d": d,
}`
	if !strings.Contains(actualSoongModuleBzl.Contents, expectedLoad) {
		t.Errorf(
			"Generated soong_module.bzl:\n\n%s\n\n"+
				"Could not find the load statement in the generated soong_module.bzl:\n%s",
			actualSoongModuleBzl.Contents,
			expectedLoad)
	}

	if !strings.Contains(actualSoongModuleBzl.Contents, expectedRuleMap) {
		t.Errorf(
			"Generated soong_module.bzl:\n\n%s\n\n"+
				"Could not find the module -> rule map in the generated soong_module.bzl:\n%s",
			actualSoongModuleBzl.Contents,
			expectedRuleMap)
	}
}
