// Copyright 2015 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 common

import (
	"path/filepath"

	"github.com/google/blueprint"
)

var (
	DeviceSharedLibrary = "shared_library"
	DeviceStaticLibrary = "static_library"
	DeviceExecutable    = "executable"
	HostSharedLibrary   = "host_shared_library"
	HostStaticLibrary   = "host_static_library"
	HostExecutable      = "host_executable"
)

type androidBaseContext interface {
	Arch() Arch
	Host() bool
	Device() bool
	Debug() bool
	AConfig() Config
}

type AndroidBaseContext interface {
	blueprint.BaseModuleContext
	androidBaseContext
}

type AndroidModuleContext interface {
	blueprint.ModuleContext
	androidBaseContext

	InstallFile(installPath, srcPath string, deps ...string) string
	InstallFileName(installPath, name, srcPath string, deps ...string) string
	CheckbuildFile(srcPath string)
}

type AndroidModule interface {
	blueprint.Module

	GenerateAndroidBuildActions(AndroidModuleContext)

	base() *AndroidModuleBase
	Disabled() bool
	HostOrDevice() HostOrDevice
}

type AndroidDynamicDepender interface {
	AndroidDynamicDependencies(ctx AndroidDynamicDependerModuleContext) []string
}

type AndroidDynamicDependerModuleContext interface {
	blueprint.DynamicDependerModuleContext
	androidBaseContext
}

type commonProperties struct {
	Name string
	Deps []string
	Tags []string

	// disabled: don't emit any build rules for this module
	Disabled bool `android:"arch_variant"`

	// multilib: control whether this module compiles for 32-bit, 64-bit, or both.  Possible values
	// are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
	// architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
	// platform
	Compile_multilib string

	// Set by ArchMutator
	CompileArch Arch `blueprint:"mutated"`

	// Set by InitAndroidModule
	HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
}

type hostAndDeviceProperties struct {
	Host_supported   bool
	Device_supported bool
}

type Multilib string

const (
	MultilibBoth   Multilib = "both"
	MultilibFirst  Multilib = "first"
	MultilibCommon Multilib = "common"
)

func InitAndroidModule(m AndroidModule,
	propertyStructs ...interface{}) (blueprint.Module, []interface{}) {

	base := m.base()
	base.module = m
	base.extendedProperties = make(map[string]struct{})

	propertyStructs = append(propertyStructs, &base.commonProperties)

	return m, propertyStructs
}

func InitAndroidArchModule(m AndroidModule, hod HostOrDeviceSupported, defaultMultilib Multilib,
	propertyStructs ...interface{}) (blueprint.Module, []interface{}) {

	_, propertyStructs = InitAndroidModule(m, propertyStructs...)

	base := m.base()
	base.commonProperties.HostOrDeviceSupported = hod

	if hod == HostAndDeviceSupported {
		// Default to module to device supported, host not supported, can override in module
		// properties
		base.hostAndDeviceProperties.Device_supported = true
		propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
	}

	return InitArchModule(m, defaultMultilib, propertyStructs...)
}

// A AndroidModuleBase object contains the properties that are common to all Android
// modules.  It should be included as an anonymous field in every module
// struct definition.  InitAndroidModule should then be called from the module's
// factory function, and the return values from InitAndroidModule should be
// returned from the factory function.
//
// The AndroidModuleBase type is responsible for implementing the
// GenerateBuildActions method to support the blueprint.Module interface. This
// method will then call the module's GenerateAndroidBuildActions method once
// for each build variant that is to be built. GenerateAndroidBuildActions is
// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
// AndroidModuleContext exposes extra functionality specific to the Android build
// system including details about the particular build variant that is to be
// generated.
//
// For example:
//
//     import (
//         "android/soong/common"
//         "github.com/google/blueprint"
//     )
//
//     type myModule struct {
//         common.AndroidModuleBase
//         properties struct {
//             MyProperty string
//         }
//     }
//
//     func NewMyModule() (blueprint.Module, []interface{}) {
//         m := &myModule{}
//         return common.InitAndroidModule(m, &m.properties)
//     }
//
//     func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
//         // Get the CPU architecture for the current build variant.
//         variantArch := ctx.Arch()
//
//         // ...
//     }
type AndroidModuleBase struct {
	// Putting the curiously recurring thing pointing to the thing that contains
	// the thing pattern to good use.
	module AndroidModule

	commonProperties        commonProperties
	hostAndDeviceProperties hostAndDeviceProperties
	generalProperties       []interface{}
	archProperties          []*archProperties
	extendedProperties      map[string]struct{}

	noAddressSanitizer bool
	installFiles       []string
	checkbuildFiles    []string
}

func (a *AndroidModuleBase) base() *AndroidModuleBase {
	return a
}

func (a *AndroidModuleBase) SetArch(arch Arch) {
	a.commonProperties.CompileArch = arch
}

func (a *AndroidModuleBase) HostOrDevice() HostOrDevice {
	return a.commonProperties.CompileArch.HostOrDevice
}

func (a *AndroidModuleBase) HostSupported() bool {
	return a.commonProperties.HostOrDeviceSupported == HostSupported ||
		a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
			a.hostAndDeviceProperties.Host_supported
}

func (a *AndroidModuleBase) DeviceSupported() bool {
	return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
		a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
			a.hostAndDeviceProperties.Device_supported
}

func (a *AndroidModuleBase) Disabled() bool {
	return a.commonProperties.Disabled
}

func (a *AndroidModuleBase) computeInstallDeps(
	ctx blueprint.ModuleContext) []string {

	result := []string{}
	ctx.VisitDepsDepthFirstIf(isFileInstaller,
		func(m blueprint.Module) {
			fileInstaller := m.(fileInstaller)
			files := fileInstaller.filesToInstall()
			result = append(result, files...)
		})

	return result
}

func (a *AndroidModuleBase) filesToInstall() []string {
	return a.installFiles
}

func (p *AndroidModuleBase) NoAddressSanitizer() bool {
	return p.noAddressSanitizer
}

func (a *AndroidModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
	if a != ctx.FinalModule().(AndroidModule).base() {
		return
	}

	allInstalledFiles := []string{}
	allCheckbuildFiles := []string{}
	ctx.VisitAllModuleVariants(func(module blueprint.Module) {
		a := module.(AndroidModule).base()
		allInstalledFiles = append(allInstalledFiles, a.installFiles...)
		allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
	})

	deps := []string{}

	if len(allInstalledFiles) > 0 {
		name := ctx.ModuleName() + "-install"
		ctx.Build(pctx, blueprint.BuildParams{
			Rule:      blueprint.Phony,
			Outputs:   []string{name},
			Implicits: allInstalledFiles,
		})
		deps = append(deps, name)
	}

	if len(allCheckbuildFiles) > 0 {
		name := ctx.ModuleName() + "-checkbuild"
		ctx.Build(pctx, blueprint.BuildParams{
			Rule:      blueprint.Phony,
			Outputs:   []string{name},
			Implicits: allCheckbuildFiles,
			Optional:  true,
		})
		deps = append(deps, name)
	}

	if len(deps) > 0 {
		ctx.Build(pctx, blueprint.BuildParams{
			Rule:      blueprint.Phony,
			Outputs:   []string{ctx.ModuleName()},
			Implicits: deps,
			Optional:  true,
		})
	}
}

func (a *AndroidModuleBase) DynamicDependencies(ctx blueprint.DynamicDependerModuleContext) []string {
	actx := &androidDynamicDependerContext{
		DynamicDependerModuleContext: ctx,
		androidBaseContextImpl: androidBaseContextImpl{
			arch:   a.commonProperties.CompileArch,
			config: ctx.Config().(Config),
		},
	}

	if dynamic, ok := a.module.(AndroidDynamicDepender); ok {
		return dynamic.AndroidDynamicDependencies(actx)
	}

	return nil
}

func (a *AndroidModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
	androidCtx := &androidModuleContext{
		ModuleContext: ctx,
		androidBaseContextImpl: androidBaseContextImpl{
			arch:   a.commonProperties.CompileArch,
			config: ctx.Config().(Config),
		},
		installDeps:        a.computeInstallDeps(ctx),
		installFiles:       a.installFiles,
		extendedProperties: a.extendedProperties,
	}

	if a.commonProperties.Disabled {
		return
	}

	a.module.GenerateAndroidBuildActions(androidCtx)
	if ctx.Failed() {
		return
	}

	a.installFiles = append(a.installFiles, androidCtx.installFiles...)
	a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)

	a.generateModuleTarget(ctx)
	if ctx.Failed() {
		return
	}
}

type androidBaseContextImpl struct {
	arch   Arch
	debug  bool
	config Config
}

type androidModuleContext struct {
	blueprint.ModuleContext
	androidBaseContextImpl
	installDeps        []string
	installFiles       []string
	checkbuildFiles    []string
	extendedProperties map[string]struct{}
}

func (a *androidModuleContext) Build(pctx *blueprint.PackageContext, params blueprint.BuildParams) {
	params.Optional = true
	a.ModuleContext.Build(pctx, params)
}

func (a *androidModuleContext) ContainsProperty(property string) bool {
	if a.ModuleContext.ContainsProperty(property) {
		return true
	}
	_, ok := a.extendedProperties[property]
	return ok
}

func (a *androidBaseContextImpl) Arch() Arch {
	return a.arch
}

func (a *androidBaseContextImpl) Host() bool {
	return a.arch.HostOrDevice.Host()
}

func (a *androidBaseContextImpl) Device() bool {
	return a.arch.HostOrDevice.Device()
}

func (a *androidBaseContextImpl) Debug() bool {
	return a.debug
}

func (a *androidBaseContextImpl) AConfig() Config {
	return a.config
}

func (a *androidModuleContext) InstallFileName(installPath, name, srcPath string,
	deps ...string) string {

	config := a.AConfig()
	var fullInstallPath string
	if a.arch.HostOrDevice.Device() {
		// TODO: replace unset with a device name once we have device targeting
		fullInstallPath = filepath.Join(config.DeviceOut(), "system",
			installPath, name)
	} else {
		fullInstallPath = filepath.Join(config.HostOut(), installPath, name)
	}

	deps = append(deps, a.installDeps...)

	a.ModuleContext.Build(pctx, blueprint.BuildParams{
		Rule:      Cp,
		Outputs:   []string{fullInstallPath},
		Inputs:    []string{srcPath},
		OrderOnly: deps,
	})

	a.installFiles = append(a.installFiles, fullInstallPath)
	return fullInstallPath
}

func (a *androidModuleContext) InstallFile(installPath, srcPath string, deps ...string) string {
	return a.InstallFileName(installPath, filepath.Base(srcPath), srcPath, deps...)
}

func (a *androidModuleContext) CheckbuildFile(srcPath string) {
	a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
}

type androidDynamicDependerContext struct {
	blueprint.DynamicDependerModuleContext
	androidBaseContextImpl
}

type fileInstaller interface {
	filesToInstall() []string
}

func isFileInstaller(m blueprint.Module) bool {
	_, ok := m.(fileInstaller)
	return ok
}

func isAndroidModule(m blueprint.Module) bool {
	_, ok := m.(AndroidModule)
	return ok
}

func ExpandSources(ctx AndroidModuleContext, srcFiles []string) []string {
	prefix := ModuleSrcDir(ctx)
	for i, srcFile := range srcFiles {
		if srcFile[0] == '-' {
			srcFiles[i] = "-" + filepath.Join(prefix, srcFile[1:])
		} else {
			srcFiles[i] = filepath.Join(prefix, srcFile)
		}
	}

	srcFiles = expandGlobs(ctx, srcFiles)
	return srcFiles
}
