// 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.GetOrDefault(ctx, nil) {
		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")

	// Suppress warnings while testing a new compiler.
	if ctx.Config().IsEnvTrue("LLVM_NEXT") {
		cflags = append(cflags, "-Wno-everything")
	}

	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
}
