// 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(),
        "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(),
        "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(),
        "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(android.NullConfig("out", "out/soong"), 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)
	}
}
