// Copyright 2018 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 xsdc

import (
	"android/soong/android"
	"android/soong/java"
	"path/filepath"
	"strings"

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

func init() {
	pctx.Import("android/soong/java/config")
	android.RegisterModuleType("xsd_config", xsdConfigFactory)

	android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
		ctx.TopDown("xsd_config", xsdConfigMutator).Parallel()
	})
}

var (
	pctx = android.NewPackageContext("android/xsdc")

	xsdc         = pctx.HostBinToolVariable("xsdcCmd", "xsdc")
	xsdcJavaRule = pctx.StaticRule("xsdcJavaRule", blueprint.RuleParams{
		Command: `rm -rf "${out}.temp" && mkdir -p "${out}.temp" && ` +
			`${xsdcCmd} $in -p $pkgName -o ${out}.temp -j && ` +
			`${config.SoongZipCmd} -jar -o ${out} -C ${out}.temp -D ${out}.temp && ` +
			`rm -rf ${out}.temp`,
		CommandDeps: []string{"${xsdcCmd}", "${config.SoongZipCmd}"},
		Description: "xsdc Java ${in} => ${out}",
	}, "pkgName")

	xsdcCppRule = pctx.StaticRule("xsdcCppRule", blueprint.RuleParams{
		Command: `rm -rf "${outDir}" && ` +
			`${xsdcCmd} $in -p $pkgName -o ${outDir} -c`,
		CommandDeps: []string{"${xsdcCmd}", "${config.SoongZipCmd}"},
		Description: "xsdc C++ ${in} => ${out}",
	}, "pkgName", "outDir")

	xsdConfigRule = pctx.StaticRule("xsdConfigRule", blueprint.RuleParams{
		Command:     "cp -f ${in} ${output}",
		Description: "copy the xsd file: ${in} => ${output}",
	}, "output")
)

type xsdConfigProperties struct {
	Srcs         []string
	Package_name *string
	Api_dir      *string
}

type xsdConfig struct {
	android.ModuleBase

	properties xsdConfigProperties

	genOutputDir android.Path
	genOutputs_j android.WritablePath
	genOutputs_c android.WritablePath
	genOutputs_h android.WritablePath

	docsPath android.Path

	xsdConfigPath android.OptionalPath
	genOutputs  android.Paths
}

var _ android.SourceFileProducer = (*xsdConfig)(nil)

type ApiToCheck struct {
	Api_file         *string
	Removed_api_file *string
	Args             *string
}

type CheckApi struct {
	Last_released ApiToCheck
	Current       ApiToCheck
}
type DroidstubsProperties struct {
	Name                 *string
	Installable          *bool
	Srcs                 []string
	Sdk_version          *string
	Args                 *string
	Api_filename         *string
	Removed_api_filename *string
	Check_api            CheckApi
}

func (module *xsdConfig) GeneratedSourceFiles() android.Paths {
	return android.Paths{module.genOutputs_c}
}

func (module *xsdConfig) Srcs() android.Paths {
	return append(module.genOutputs, module.genOutputs_j)
}

func (module *xsdConfig) GeneratedDeps() android.Paths {
	return android.Paths{module.genOutputs_h}
}

func (module *xsdConfig) GeneratedHeaderDirs() android.Paths {
	return android.Paths{module.genOutputDir}
}

func (module *xsdConfig) DepsMutator(ctx android.BottomUpMutatorContext) {
	android.ExtractSourcesDeps(ctx, module.properties.Srcs)
}

func (module *xsdConfig) generateXsdConfig(ctx android.ModuleContext) {
	if !module.xsdConfigPath.Valid() {
		return
	}

	output := android.PathForModuleGen(ctx, module.Name()+".xsd")
	module.genOutputs = append(module.genOutputs, output)

	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
		Rule:   xsdConfigRule,
		Input:  module.xsdConfigPath.Path(),
		Output: output,
		Args: map[string]string{
			"output": output.String(),
		},
	})
}

func (module *xsdConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	if len(module.properties.Srcs) != 1 {
		ctx.PropertyErrorf("srcs", "xsd_config must be one src")
	}

	ctx.VisitDirectDeps(func(to android.Module) {
		if doc, ok := to.(java.ApiFilePath); ok {
			module.docsPath = doc.ApiFilePath()
		}
	})

	srcFiles := ctx.ExpandSources(module.properties.Srcs, nil)
	xsdFile := srcFiles[0]

	pkgName := *module.properties.Package_name
	filenameStem := strings.Replace(pkgName, ".", "_", -1)

	module.genOutputs_j = android.PathForModuleGen(ctx, "java", filenameStem+"_xsdcgen.srcjar")

	ctx.Build(pctx, android.BuildParams{
		Rule:        xsdcJavaRule,
		Description: "xsdc " + xsdFile.String(),
		Input:       xsdFile,
		Implicit:    module.docsPath,
		Output:      module.genOutputs_j,
		Args: map[string]string{
			"pkgName": pkgName,
		},
	})

	module.genOutputs_c = android.PathForModuleGen(ctx, "cpp", filenameStem+".cpp")
	module.genOutputs_h = android.PathForModuleGen(ctx, "cpp", "include/"+filenameStem+".h")
	module.genOutputDir = android.PathForModuleGen(ctx, "cpp", "include")

	ctx.Build(pctx, android.BuildParams{
		Rule:           xsdcCppRule,
		Description:    "xsdc " + xsdFile.String(),
		Input:          xsdFile,
		Implicit:       module.docsPath,
		Output:         module.genOutputs_c,
		ImplicitOutput: module.genOutputs_h,
		Args: map[string]string{
			"pkgName": pkgName,
			"outDir":  android.PathForModuleGen(ctx, "cpp").String(),
		},
	})
	module.xsdConfigPath = android.ExistentPathForSource(ctx, xsdFile.String())
	module.generateXsdConfig(ctx)
}

func xsdConfigMutator(mctx android.TopDownMutatorContext) {
	if module, ok := mctx.Module().(*xsdConfig); ok {
		name := module.BaseModuleName()

		args := " --stub-packages " + *module.properties.Package_name +
			" --hide MissingPermission --hide BroadcastBehavior" +
			" --hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol" +
			" --hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo"

		api_dir := proptools.StringDefault(module.properties.Api_dir, "api")

		currentApiFileName := filepath.Join(api_dir, "current.txt")
		removedApiFileName := filepath.Join(api_dir, "removed.txt")

		check_api := CheckApi{}

		check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
		check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)

		check_api.Last_released.Api_file = proptools.StringPtr(
			filepath.Join(api_dir, "last_current.txt"))
		check_api.Last_released.Removed_api_file = proptools.StringPtr(
			filepath.Join(api_dir, "last_removed.txt"))

		mctx.CreateModule(java.DroidstubsFactory, &DroidstubsProperties{
			Name:                 proptools.StringPtr(name + ".docs"),
			Srcs:                 []string{":" + name},
			Args:                 proptools.StringPtr(args),
			Api_filename:         proptools.StringPtr(currentApiFileName),
			Removed_api_filename: proptools.StringPtr(removedApiFileName),
			Check_api:            check_api,
			Installable:          proptools.BoolPtr(false),
			Sdk_version:          proptools.StringPtr("core_platform"),
		})
	}
}

func xsdConfigFactory() android.Module {
	module := &xsdConfig{}
	module.AddProperties(&module.properties)
	android.InitAndroidModule(module)

	return module
}
