// Copyright 2020 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 rust

import (
	"strings"

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

	"android/soong/android"
	"android/soong/cc"
	cc_config "android/soong/cc/config"
)

var (
	defaultBindgenFlags = []string{""}

	// bindgen should specify its own Clang revision so updating Clang isn't potentially blocked on bindgen failures.
	bindgenClangVersion = "clang-r530567"

	_ = pctx.VariableFunc("bindgenClangVersion", func(ctx android.PackageVarContext) string {
		if override := ctx.Config().Getenv("LLVM_BINDGEN_PREBUILTS_VERSION"); override != "" {
			return override
		}
		return bindgenClangVersion
	})

	//TODO(b/160803703) Use a prebuilt bindgen instead of the built bindgen.
	_ = pctx.HostBinToolVariable("bindgenCmd", "bindgen")
	_ = pctx.VariableFunc("bindgenHostPrebuiltTag", func(ctx android.PackageVarContext) string {
		if ctx.Config().UseHostMusl() {
			// This is a hack to use the glibc bindgen binary until we have a musl version checked in.
			return "linux-x86"
		} else {
			return "${config.HostPrebuiltTag}"
		}
	})
	_ = pctx.VariableFunc("bindgenClangLibdir", func(ctx android.PackageVarContext) string {
		if ctx.Config().UseHostMusl() {
			return "musl/lib/"
		} else {
			return "lib/"
		}
	})
	_ = pctx.SourcePathVariable("bindgenClang",
		"${cc_config.ClangBase}/${bindgenHostPrebuiltTag}/${bindgenClangVersion}/bin/clang")
	_ = pctx.SourcePathVariable("bindgenLibClang",
		"${cc_config.ClangBase}/${bindgenHostPrebuiltTag}/${bindgenClangVersion}/${bindgenClangLibdir}")

	//TODO(ivanlozano) Switch this to RuleBuilder
	//
	//TODO Pass the flag files directly to bindgen e.g. with @file when it supports that.
	//See https://github.com/rust-lang/rust-bindgen/issues/2508.
	bindgen = pctx.AndroidStaticRule("bindgen",
		blueprint.RuleParams{
			Command: "CLANG_PATH=$bindgenClang LIBCLANG_PATH=$bindgenLibClang RUSTFMT=${config.RustBin}/rustfmt " +
				"$cmd $flags $$(cat $flagfiles) $in -o $out -- -MD -MF $out.d $cflags",
			CommandDeps: []string{"$cmd"},
			Deps:        blueprint.DepsGCC,
			Depfile:     "$out.d",
		},
		"cmd", "flags", "flagfiles", "cflags")
)

func init() {
	android.RegisterModuleType("rust_bindgen", RustBindgenFactory)
	android.RegisterModuleType("rust_bindgen_host", RustBindgenHostFactory)
}

var _ SourceProvider = (*bindgenDecorator)(nil)

type BindgenProperties struct {
	// The wrapper header file. By default this is assumed to be a C header unless the extension is ".hh" or ".hpp".
	// This is used to specify how to interpret the header and determines which '-std' flag to use by default.
	//
	// If your C++ header must have some other extension, then the default behavior can be overridden by setting the
	// cpp_std property.
	Wrapper_src *string `android:"path,arch_variant"`

	// list of bindgen-specific flags and options
	Bindgen_flags []string `android:"arch_variant"`

	// list of files containing extra bindgen flags
	Bindgen_flag_files []string `android:"arch_variant"`

	// module name of a custom binary/script which should be used instead of the 'bindgen' binary. This custom
	// binary must expect arguments in a similar fashion to bindgen, e.g.
	//
	// "my_bindgen [flags] wrapper_header.h -o [output_path] -- [clang flags]"
	Custom_bindgen string

	// flag to indicate if bindgen should handle `static inline` functions (default is false).
	// If true, Static_inline_library must be set.
	Handle_static_inline *bool

	// module name of the corresponding cc_library_static which includes the static_inline wrapper
	// generated functions from bindgen. Must be used together with handle_static_inline.
	//
	// If there are no static inline functions provided through the header file,
	// then bindgen (as of 0.69.2) will silently fail to output a .c file, and
	// the cc_library_static depending on this module will fail compilation.
	Static_inline_library *string
}

type bindgenDecorator struct {
	*BaseSourceProvider

	Properties      BindgenProperties
	ClangProperties cc.RustBindgenClangProperties
}

func (b *bindgenDecorator) getStdVersion(ctx ModuleContext, src android.Path) (string, bool) {
	// Assume headers are C headers
	isCpp := false
	stdVersion := ""

	switch src.Ext() {
	case ".hpp", ".hh":
		isCpp = true
	}

	if String(b.ClangProperties.Cpp_std) != "" && String(b.ClangProperties.C_std) != "" {
		ctx.PropertyErrorf("c_std", "c_std and cpp_std cannot both be defined at the same time.")
	}

	if b.ClangProperties.Cpp_std != nil {
		isCpp = true
		if String(b.ClangProperties.Cpp_std) == "experimental" {
			stdVersion = cc_config.ExperimentalCppStdVersion
		} else if String(b.ClangProperties.Cpp_std) == "default" || String(b.ClangProperties.Cpp_std) == "" {
			stdVersion = cc_config.CppStdVersion
		} else {
			stdVersion = String(b.ClangProperties.Cpp_std)
		}
	} else if b.ClangProperties.C_std != nil {
		isCpp = false
		if String(b.ClangProperties.C_std) == "experimental" {
			stdVersion = cc_config.ExperimentalCStdVersion
		} else if String(b.ClangProperties.C_std) == "default" || String(b.ClangProperties.C_std) == "" {
			stdVersion = cc_config.CStdVersion
		} else {
			stdVersion = String(b.ClangProperties.C_std)
		}
	} else if isCpp {
		stdVersion = cc_config.CppStdVersion
	} else {
		stdVersion = cc_config.CStdVersion
	}

	return stdVersion, isCpp
}

func (b *bindgenDecorator) GenerateSource(ctx ModuleContext, deps PathDeps) android.Path {
	ccToolchain := ctx.RustModule().ccToolchain(ctx)

	var cflags []string
	var implicits android.Paths
	var implicitOutputs android.WritablePaths
	var validations android.Paths

	if Bool(b.Properties.Handle_static_inline) && b.Properties.Static_inline_library == nil {
		ctx.PropertyErrorf("handle_static_inline",
			"requires declaring static_inline_library to the corresponding cc_library module that includes the generated C source from bindgen.")
	}

	if b.Properties.Static_inline_library != nil && !Bool(b.Properties.Handle_static_inline) {
		ctx.PropertyErrorf("static_inline_library",
			"requires declaring handle_static_inline.")
	}

	implicits = append(implicits, deps.depGeneratedHeaders...)

	// Default clang flags
	cflags = append(cflags, "${cc_config.CommonGlobalCflags}")
	if ctx.Device() {
		cflags = append(cflags, "${cc_config.DeviceGlobalCflags}")
	}

	// Toolchain clang flags
	cflags = append(cflags, "-target "+ccToolchain.ClangTriple())
	cflags = append(cflags, strings.ReplaceAll(ccToolchain.Cflags(), "${config.", "${cc_config."))
	cflags = append(cflags, strings.ReplaceAll(ccToolchain.ToolchainCflags(), "${config.", "${cc_config."))

	if ctx.RustModule().InVendorOrProduct() {
		cflags = append(cflags, "-D__ANDROID_VNDK__")
		if ctx.RustModule().InVendor() {
			cflags = append(cflags, "-D__ANDROID_VENDOR__")
		} else if ctx.RustModule().InProduct() {
			cflags = append(cflags, "-D__ANDROID_PRODUCT__")
		}

		// Define __ANDROID_VENDOR_API__ for both product and vendor variants
		// because they both use the same LLNDK libraries.
		vendorApiLevel := ctx.Config().VendorApiLevel()
		if vendorApiLevel == "" {
			// TODO(b/314036847): This is a fallback for UDC targets.
			// This must be a build failure when UDC is no longer built
			// from this source tree.
			vendorApiLevel = ctx.Config().PlatformSdkVersion().String()
		}
		cflags = append(cflags, "-D__ANDROID_VENDOR_API__="+vendorApiLevel)
	}

	if ctx.RustModule().InRecovery() {
		cflags = append(cflags, "-D__ANDROID_RECOVERY__")
	}

	if mctx, ok := ctx.(*moduleContext); ok && mctx.apexVariationName() != "" {
		cflags = append(cflags, "-D__ANDROID_APEX__")
	}

	if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
		cflags = append(cflags, "-D__ANDROID_NATIVE_BRIDGE__")
	}

	// Dependency clang flags and include paths
	cflags = append(cflags, deps.depClangFlags...)
	for _, include := range deps.depIncludePaths {
		cflags = append(cflags, "-I"+include.String())
	}
	for _, include := range deps.depSystemIncludePaths {
		cflags = append(cflags, "-isystem "+include.String())
	}

	esc := proptools.NinjaAndShellEscapeList

	// Filter out invalid cflags
	cflagsProp := b.ClangProperties.Cflags.GetOrDefault(ctx, nil)
	for _, flag := range cflagsProp {
		if flag == "-x c++" || flag == "-xc++" {
			ctx.PropertyErrorf("cflags",
				"-x c++ should not be specified in cflags; setting cpp_std specifies this is a C++ header, or change the file extension to '.hpp' or '.hh'")
		}
		if strings.HasPrefix(flag, "-std=") {
			ctx.PropertyErrorf("cflags",
				"-std should not be specified in cflags; instead use c_std or cpp_std")
		}
	}

	// Module defined clang flags and include paths
	cflags = append(cflags, esc(cflagsProp)...)
	for _, include := range b.ClangProperties.Local_include_dirs {
		cflags = append(cflags, "-I"+android.PathForModuleSrc(ctx, include).String())
		implicits = append(implicits, android.PathForModuleSrc(ctx, include))
	}

	bindgenFlags := defaultBindgenFlags
	bindgenFlags = append(bindgenFlags, esc(b.Properties.Bindgen_flags)...)
	if Bool(b.Properties.Handle_static_inline) {
		outputStaticFnsFile := android.PathForModuleOut(ctx, b.BaseSourceProvider.getStem(ctx)+".c")
		implicitOutputs = append(implicitOutputs, outputStaticFnsFile)
		validations = append(validations, outputStaticFnsFile)
		bindgenFlags = append(bindgenFlags, []string{"--experimental", "--wrap-static-fns", "--wrap-static-fns-path=" + outputStaticFnsFile.String()}...)
	}

	// cat reads from stdin if its command line is empty,
	// so we pass in /dev/null if there are no other flag files
	bindgenFlagFiles := []string{"/dev/null"}
	for _, flagFile := range b.Properties.Bindgen_flag_files {
		bindgenFlagFiles = append(bindgenFlagFiles, android.PathForModuleSrc(ctx, flagFile).String())
		implicits = append(implicits, android.PathForModuleSrc(ctx, flagFile))
	}

	wrapperFile := android.OptionalPathForModuleSrc(ctx, b.Properties.Wrapper_src)
	if !wrapperFile.Valid() {
		ctx.PropertyErrorf("wrapper_src", "invalid path to wrapper source")
	}

	// Add C std version flag
	stdVersion, isCpp := b.getStdVersion(ctx, wrapperFile.Path())
	cflags = append(cflags, "-std="+stdVersion)

	// Specify the header source language to avoid ambiguity.
	if isCpp {
		cflags = append(cflags, "-x c++")
		// Add any C++ only flags.
		cflags = append(cflags, esc(b.ClangProperties.Cppflags.GetOrDefault(ctx, nil))...)
	} else {
		cflags = append(cflags, "-x c")
	}

	// clang-r468909b complains about the -x c in the flags in clang-sys parse_search_paths:
	// clang: error: '-x c' after last input file has no effect [-Werror,-Wunused-command-line-argument]
	cflags = append(cflags, "-Wno-unused-command-line-argument")

	// The Clang version used by CXX can be newer than the one used by Bindgen, and uses warning related flags that
	// it cannot recognize. Turn off unknown warning flags warning.
	cflags = append(cflags, "-Wno-unknown-warning-option")

	outputFile := android.PathForModuleOut(ctx, b.BaseSourceProvider.getStem(ctx)+".rs")

	var cmd, cmdDesc string
	if b.Properties.Custom_bindgen != "" {
		cmd = ctx.GetDirectDepWithTag(b.Properties.Custom_bindgen, customBindgenDepTag).(android.HostToolProvider).HostToolPath().String()
		cmdDesc = b.Properties.Custom_bindgen
	} else {
		cmd = "$bindgenCmd"
		cmdDesc = "bindgen"
	}

	ctx.Build(pctx, android.BuildParams{
		Rule:            bindgen,
		Description:     strings.Join([]string{cmdDesc, wrapperFile.Path().Rel()}, " "),
		Output:          outputFile,
		Input:           wrapperFile.Path(),
		Implicits:       implicits,
		ImplicitOutputs: implicitOutputs,
		Validations:     validations,
		Args: map[string]string{
			"cmd":       cmd,
			"flags":     strings.Join(bindgenFlags, " "),
			"flagfiles": strings.Join(bindgenFlagFiles, " "),
			"cflags":    strings.Join(cflags, " "),
		},
	})

	b.BaseSourceProvider.OutputFiles = android.Paths{outputFile}

	// Append any additional implicit outputs after the entry point source.
	// We append any generated .c file here so it can picked up by cc_library_static modules.
	// Those CC modules need to be sure not to pass any included .rs files to Clang.
	// We don't have to worry about the additional .c files for Rust modules as only the entry point
	// is passed to rustc.
	b.BaseSourceProvider.OutputFiles = append(b.BaseSourceProvider.OutputFiles, implicitOutputs.Paths()...)

	return outputFile
}

func (b *bindgenDecorator) SourceProviderProps() []interface{} {
	return append(b.BaseSourceProvider.SourceProviderProps(),
		&b.Properties, &b.ClangProperties)
}

// rust_bindgen generates Rust FFI bindings to C libraries using bindgen given a wrapper header as the primary input.
// Bindgen has a number of flags to control the generated source, and additional flags can be passed to clang to ensure
// the header and generated source is appropriately handled. It is recommended to add it as a dependency in the
// rlibs or rustlibs property. It may also be added in the srcs property for external crates, using the ":"
// prefix.
func RustBindgenFactory() android.Module {
	module, _ := NewRustBindgen(android.HostAndDeviceSupported)
	return module.Init()
}

func RustBindgenHostFactory() android.Module {
	module, _ := NewRustBindgen(android.HostSupported)
	return module.Init()
}

func NewRustBindgen(hod android.HostOrDeviceSupported) (*Module, *bindgenDecorator) {
	bindgen := &bindgenDecorator{
		BaseSourceProvider: NewSourceProvider(),
		Properties:         BindgenProperties{},
		ClangProperties:    cc.RustBindgenClangProperties{},
	}

	module := NewSourceProviderModule(hod, bindgen, false, false)

	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
		type stub_props struct {
			Visibility []string
		}
		props := &stub_props{[]string{":__subpackages__"}}
		ctx.PrependProperties(props)
	})

	return module, bindgen
}

func (b *bindgenDecorator) SourceProviderDeps(ctx DepsContext, deps Deps) Deps {
	deps = b.BaseSourceProvider.SourceProviderDeps(ctx, deps)
	if ctx.toolchain().Bionic() && !ctx.RustModule().compiler.noStdlibs() {
		deps = bionicDeps(ctx, deps, false)
	} else if ctx.Os() == android.LinuxMusl {
		deps = muslDeps(ctx, deps, false)
	}

	if !ctx.RustModule().Source() && b.Properties.Static_inline_library != nil {
		// This is not the source variant, so add the static inline library as a dependency.
		//
		// This is necessary to avoid a circular dependency between the source variant and the
		// dependent cc module.
		deps.StaticLibs = append(deps.StaticLibs, String(b.Properties.Static_inline_library))
	}

	deps.SharedLibs = append(deps.SharedLibs, b.ClangProperties.Shared_libs.GetOrDefault(ctx, nil)...)
	deps.StaticLibs = append(deps.StaticLibs, b.ClangProperties.Static_libs.GetOrDefault(ctx, nil)...)
	deps.HeaderLibs = append(deps.HeaderLibs, b.ClangProperties.Header_libs.GetOrDefault(ctx, nil)...)
	return deps
}
