// Copyright (C) 2019 The Android Open Source Project
//
// 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 sdk

import (
	"fmt"
	"io"

	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"

	"android/soong/android"
	// This package doesn't depend on the apex package, but import it to make its mutators to be
	// registered before mutators in this package. See RegisterPostDepsMutators for more details.
	_ "android/soong/apex"
)

func init() {
	pctx.Import("android/soong/android")
	pctx.Import("android/soong/java/config")

	registerSdkBuildComponents(android.InitRegistrationContext)
}

func registerSdkBuildComponents(ctx android.RegistrationContext) {
	ctx.RegisterModuleType("sdk", SdkModuleFactory)
	ctx.RegisterModuleType("sdk_snapshot", SnapshotModuleFactory)
}

type sdk struct {
	android.ModuleBase
	android.DefaultableModuleBase

	// The dynamically generated information about the registered SdkMemberType
	dynamicSdkMemberTypes *dynamicSdkMemberTypes

	// The dynamically created instance of the properties struct containing the sdk member type
	// list properties, e.g. java_libs.
	dynamicMemberTypeListProperties interface{}

	// The dynamically generated information about the registered SdkMemberTrait
	dynamicSdkMemberTraits *dynamicSdkMemberTraits

	// The dynamically created instance of the properties struct containing the sdk member trait
	// list properties.
	dynamicMemberTraitListProperties interface{}

	// Information about the OsType specific member variants depended upon by this variant.
	//
	// Set by OsType specific variants in the collectMembers() method and used by the
	// CommonOS variant when building the snapshot. That work is all done on separate
	// calls to the sdk.GenerateAndroidBuildActions method which is guaranteed to be
	// called for the OsType specific variants before the CommonOS variant (because
	// the latter depends on the former).
	memberVariantDeps []sdkMemberVariantDep

	// The multilib variants that are used by this sdk variant.
	multilibUsages multilibUsage

	properties sdkProperties

	snapshotFile android.OptionalPath

	infoFile android.OptionalPath

	// The builder, preserved for testing.
	builderForTests *snapshotBuilder
}

type sdkProperties struct {
	Snapshot bool `blueprint:"mutated"`

	// True if this is a module_exports (or module_exports_snapshot) module type.
	Module_exports bool `blueprint:"mutated"`
}

// sdk defines an SDK which is a logical group of modules (e.g. native libs, headers, java libs, etc.)
// which Mainline modules like APEX can choose to build with.
func SdkModuleFactory() android.Module {
	return newSdkModule(false)
}

func newSdkModule(moduleExports bool) *sdk {
	s := &sdk{}
	s.properties.Module_exports = moduleExports
	// Get the dynamic sdk member type data for the currently registered sdk member types.
	sdkMemberTypeKey, sdkMemberTypes := android.RegisteredSdkMemberTypes(moduleExports)
	s.dynamicSdkMemberTypes = getDynamicSdkMemberTypes(sdkMemberTypeKey, sdkMemberTypes)
	// Create an instance of the dynamically created struct that contains all the
	// properties for the member type specific list properties.
	s.dynamicMemberTypeListProperties = s.dynamicSdkMemberTypes.createMemberTypeListProperties()

	sdkMemberTraitsKey, sdkMemberTraits := android.RegisteredSdkMemberTraits()
	s.dynamicSdkMemberTraits = getDynamicSdkMemberTraits(sdkMemberTraitsKey, sdkMemberTraits)
	// Create an instance of the dynamically created struct that contains all the properties for the
	// member trait specific list properties.
	s.dynamicMemberTraitListProperties = s.dynamicSdkMemberTraits.createMemberTraitListProperties()

	// Create a wrapper around the dynamic trait specific properties so that they have to be
	// specified within a traits:{} section in the .bp file.
	traitsWrapper := struct {
		Traits interface{}
	}{s.dynamicMemberTraitListProperties}

	s.AddProperties(&s.properties, s.dynamicMemberTypeListProperties, &traitsWrapper)

	android.InitCommonOSAndroidMultiTargetsArchModule(s, android.HostAndDeviceSupported, android.MultilibCommon)
	android.InitDefaultableModule(s)
	android.AddLoadHook(s, func(ctx android.LoadHookContext) {
		type props struct {
			Compile_multilib *string
		}
		p := &props{Compile_multilib: proptools.StringPtr("both")}
		ctx.PrependProperties(p)
	})
	return s
}

// sdk_snapshot is a snapshot of an SDK. This is an auto-generated module.
func SnapshotModuleFactory() android.Module {
	s := newSdkModule(false)
	s.properties.Snapshot = true
	return s
}

func (s *sdk) memberTypeListProperties() []*sdkMemberTypeListProperty {
	return s.dynamicSdkMemberTypes.memberTypeListProperties
}

func (s *sdk) memberTypeListProperty(memberType android.SdkMemberType) *sdkMemberTypeListProperty {
	return s.dynamicSdkMemberTypes.memberTypeToProperty[memberType]
}

// memberTraitListProperties returns the list of *sdkMemberTraitListProperty instances for this sdk.
func (s *sdk) memberTraitListProperties() []*sdkMemberTraitListProperty {
	return s.dynamicSdkMemberTraits.memberTraitListProperties
}

func (s *sdk) snapshot() bool {
	return s.properties.Snapshot
}

func (s *sdk) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	if s.snapshot() {
		// We don't need to create a snapshot out of sdk_snapshot.
		// That doesn't make sense. We need a snapshot to create sdk_snapshot.
		return
	}

	// This method is guaranteed to be called on OsType specific variants before it is called
	// on their corresponding CommonOS variant.
	if !s.IsCommonOSVariant() {
		// Update the OsType specific sdk variant with information about its members.
		s.collectMembers(ctx)
	} else {
		// Get the OsType specific variants on which the CommonOS depends.
		osSpecificVariants := android.GetOsSpecificVariantsOfCommonOSVariant(ctx)
		var sdkVariants []*sdk
		for _, m := range osSpecificVariants {
			if sdkVariant, ok := m.(*sdk); ok {
				sdkVariants = append(sdkVariants, sdkVariant)
			}
		}

		// Generate the snapshot from the member info.
		s.buildSnapshot(ctx, sdkVariants)
	}

	if s.snapshotFile.Valid() {
		ctx.SetOutputFiles([]android.Path{s.snapshotFile.Path()}, "")
	}
}

func (s *sdk) AndroidMkEntries() []android.AndroidMkEntries {
	if !s.snapshotFile.Valid() != !s.infoFile.Valid() {
		panic("Snapshot (%q) and info file (%q) should both be set or neither should be set.")
	} else if !s.snapshotFile.Valid() {
		return []android.AndroidMkEntries{}
	}

	return []android.AndroidMkEntries{android.AndroidMkEntries{
		Class:      "FAKE",
		OutputFile: s.snapshotFile,
		DistFiles:  android.MakeDefaultDistFiles(s.snapshotFile.Path(), s.infoFile.Path()),
		Include:    "$(BUILD_PHONY_PACKAGE)",
		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
				entries.SetBool("LOCAL_DONT_CHECK_MODULE", true)
			},
		},
		ExtraFooters: []android.AndroidMkExtraFootersFunc{
			func(w io.Writer, name, prefix, moduleDir string) {
				// Allow the sdk to be built by simply passing its name on the command line.
				fmt.Fprintln(w, ".PHONY:", s.Name())
				fmt.Fprintln(w, s.Name()+":", s.snapshotFile.String())

				// Allow the sdk info to be built by simply passing its name on the command line.
				infoTarget := s.Name() + ".info"
				fmt.Fprintln(w, ".PHONY:", infoTarget)
				fmt.Fprintln(w, infoTarget+":", s.infoFile.String())
			},
		},
	}}
}

// gatherTraits gathers the traits from the dynamically generated trait specific properties.
//
// Returns a map from member name to the set of required traits.
func (s *sdk) gatherTraits() map[string]android.SdkMemberTraitSet {
	traitListByMember := map[string][]android.SdkMemberTrait{}
	for _, memberListProperty := range s.memberTraitListProperties() {
		names := memberListProperty.getter(s.dynamicMemberTraitListProperties)
		for _, name := range names {
			traitListByMember[name] = append(traitListByMember[name], memberListProperty.memberTrait)
		}
	}

	traitSetByMember := map[string]android.SdkMemberTraitSet{}
	for name, list := range traitListByMember {
		traitSetByMember[name] = android.NewSdkMemberTraitSet(list)
	}

	return traitSetByMember
}

// newDependencyContext creates a new SdkDependencyContext for this sdk.
func (s *sdk) newDependencyContext(mctx android.BottomUpMutatorContext) android.SdkDependencyContext {
	traits := s.gatherTraits()

	return &dependencyContext{
		BottomUpMutatorContext: mctx,
		requiredTraits:         traits,
	}
}

type dependencyContext struct {
	android.BottomUpMutatorContext

	// Map from member name to the set of traits that the sdk requires the member provides.
	requiredTraits map[string]android.SdkMemberTraitSet
}

func (d *dependencyContext) RequiredTraits(name string) android.SdkMemberTraitSet {
	if s, ok := d.requiredTraits[name]; ok {
		return s
	} else {
		return android.EmptySdkMemberTraitSet()
	}
}

func (d *dependencyContext) RequiresTrait(name string, trait android.SdkMemberTrait) bool {
	return d.RequiredTraits(name).Contains(trait)
}

var _ android.SdkDependencyContext = (*dependencyContext)(nil)

type dependencyTag struct {
	blueprint.BaseDependencyTag
}

// Mark this tag so dependencies that use it are excluded from APEX contents.
func (t dependencyTag) ExcludeFromApexContents() {}

var _ android.ExcludeFromApexContentsTag = dependencyTag{}

func (s *sdk) DepsMutator(mctx android.BottomUpMutatorContext) {
	// Add dependencies from non CommonOS variants to the sdk member variants.
	if s.IsCommonOSVariant() {
		return
	}

	ctx := s.newDependencyContext(mctx)
	for _, memberListProperty := range s.memberTypeListProperties() {
		if memberListProperty.getter == nil {
			continue
		}
		names := memberListProperty.getter(s.dynamicMemberTypeListProperties)
		if len(names) > 0 {
			memberType := memberListProperty.memberType

			// Verify that the member type supports the specified traits.
			supportedTraits := memberType.SupportedTraits()
			for _, name := range names {
				requiredTraits := ctx.RequiredTraits(name)
				unsupportedTraits := requiredTraits.Subtract(supportedTraits)
				if !unsupportedTraits.Empty() {
					ctx.ModuleErrorf("sdk member %q has traits %s that are unsupported by its member type %q",
						name, unsupportedTraits, memberType.SdkPropertyName())
				}
			}

			// Add dependencies using the appropriate tag.
			tag := memberListProperty.dependencyTag
			memberType.AddDependencies(ctx, tag, names)
		}
	}
}
