package bp2build

import (
	"testing"

	"android/soong/android"
	"android/soong/bazel"
)

var (
	// A default configuration for tests to not have to specify bp2build_available on top level targets.
	bp2buildConfig = android.Bp2BuildConfig{
		android.BP2BUILD_TOPLEVEL: android.Bp2BuildDefaultTrueRecursively,
	}

	buildDir string
)

type nestedProps struct {
	Nested_prop string
}

type customProps struct {
	Bool_prop     bool
	Bool_ptr_prop *bool
	// Ensure that properties tagged `blueprint:mutated` are omitted
	Int_prop         int `blueprint:"mutated"`
	Int64_ptr_prop   *int64
	String_prop      string
	String_ptr_prop  *string
	String_list_prop []string

	Nested_props     nestedProps
	Nested_props_ptr *nestedProps

	Arch_paths []string `android:"path,arch_variant"`
}

type customModule struct {
	android.ModuleBase
	android.BazelModuleBase

	props customProps
}

func errored(t *testing.T, desc string, errs []error) bool {
	t.Helper()
	if len(errs) > 0 {
		for _, err := range errs {
			t.Errorf("%s: %s", desc, err)
		}
		return true
	}
	return false
}

// OutputFiles is needed because some instances of this module use dist with a
// tag property which requires the module implements OutputFileProducer.
func (m *customModule) OutputFiles(tag string) (android.Paths, error) {
	return android.PathsForTesting("path" + tag), nil
}

func (m *customModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	// nothing for now.
}

func customModuleFactoryBase() android.Module {
	module := &customModule{}
	module.AddProperties(&module.props)
	android.InitBazelModule(module)
	return module
}

func customModuleFactory() android.Module {
	m := customModuleFactoryBase()
	android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibBoth)
	return m
}

type testProps struct {
	Test_prop struct {
		Test_string_prop string
	}
}

type customTestModule struct {
	android.ModuleBase

	props      customProps
	test_props testProps
}

func (m *customTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	// nothing for now.
}

func customTestModuleFactoryBase() android.Module {
	m := &customTestModule{}
	m.AddProperties(&m.props)
	m.AddProperties(&m.test_props)
	return m
}

func customTestModuleFactory() android.Module {
	m := customTestModuleFactoryBase()
	android.InitAndroidModule(m)
	return m
}

type customDefaultsModule struct {
	android.ModuleBase
	android.DefaultsModuleBase
}

func customDefaultsModuleFactoryBase() android.DefaultsModule {
	module := &customDefaultsModule{}
	module.AddProperties(&customProps{})
	return module
}

func customDefaultsModuleFactoryBasic() android.Module {
	return customDefaultsModuleFactoryBase()
}

func customDefaultsModuleFactory() android.Module {
	m := customDefaultsModuleFactoryBase()
	android.InitDefaultsModule(m)
	return m
}

type customBazelModuleAttributes struct {
	String_prop      string
	String_list_prop []string
	Arch_paths       bazel.LabelListAttribute
}

type customBazelModule struct {
	android.BazelTargetModuleBase
	customBazelModuleAttributes
}

func customBazelModuleFactory() android.Module {
	module := &customBazelModule{}
	module.AddProperties(&module.customBazelModuleAttributes)
	android.InitBazelTargetModule(module)
	return module
}

func (m *customBazelModule) Name() string                                          { return m.BaseModuleName() }
func (m *customBazelModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {}

func customBp2BuildMutator(ctx android.TopDownMutatorContext) {
	if m, ok := ctx.Module().(*customModule); ok {
		if !m.ConvertWithBp2build(ctx) {
			return
		}

		paths := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.props.Arch_paths))

		for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) {
			for config, props := range configToProps {
				if archProps, ok := props.(*customProps); ok && archProps.Arch_paths != nil {
					paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, archProps.Arch_paths))
				}
			}
		}

		attrs := &customBazelModuleAttributes{
			String_prop:      m.props.String_prop,
			String_list_prop: m.props.String_list_prop,
			Arch_paths:       paths,
		}

		props := bazel.BazelTargetModuleProperties{
			Rule_class: "custom",
		}

		ctx.CreateBazelTargetModule(customBazelModuleFactory, m.Name(), props, attrs)
	}
}

// A bp2build mutator that uses load statements and creates a 1:M mapping from
// module to target.
func customBp2BuildMutatorFromStarlark(ctx android.TopDownMutatorContext) {
	if m, ok := ctx.Module().(*customModule); ok {
		if !m.ConvertWithBp2build(ctx) {
			return
		}

		baseName := m.Name()
		attrs := &customBazelModuleAttributes{}

		myLibraryProps := bazel.BazelTargetModuleProperties{
			Rule_class:        "my_library",
			Bzl_load_location: "//build/bazel/rules:rules.bzl",
		}
		ctx.CreateBazelTargetModule(customBazelModuleFactory, baseName, myLibraryProps, attrs)

		protoLibraryProps := bazel.BazelTargetModuleProperties{
			Rule_class:        "proto_library",
			Bzl_load_location: "//build/bazel/rules:proto.bzl",
		}
		ctx.CreateBazelTargetModule(customBazelModuleFactory, baseName+"_proto_library_deps", protoLibraryProps, attrs)

		myProtoLibraryProps := bazel.BazelTargetModuleProperties{
			Rule_class:        "my_proto_library",
			Bzl_load_location: "//build/bazel/rules:proto.bzl",
		}
		ctx.CreateBazelTargetModule(customBazelModuleFactory, baseName+"_my_proto_library_deps", myProtoLibraryProps, attrs)
	}
}

// Helper method for tests to easily access the targets in a dir.
func generateBazelTargetsForDir(codegenCtx *CodegenContext, dir string) BazelTargets {
	// TODO: Set generateFilegroups to true and/or remove the generateFilegroups argument completely
	buildFileToTargets, _, _ := GenerateBazelTargets(codegenCtx, false)
	return buildFileToTargets[dir]
}
