// 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}", "-nostdlibinc")
	}

	// 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
}
