// Copyright 2016 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 cc

import (
	"fmt"
	"path/filepath"

	"github.com/google/blueprint"

	"android/soong/android"
)

var (
	versionBionicHeaders = pctx.AndroidStaticRule("versionBionicHeaders",
		blueprint.RuleParams{
			// The `&& touch $out` isn't really necessary, but Blueprint won't
			// let us have only implicit outputs.
			Command:     "$versionerCmd -o $outDir $srcDir $depsPath && touch $out",
			CommandDeps: []string{"$versionerCmd"},
		},
		"depsPath", "srcDir", "outDir")

	preprocessNdkHeader = pctx.AndroidStaticRule("preprocessNdkHeader",
		blueprint.RuleParams{
			Command:     "$preprocessor -o $out $in",
			CommandDeps: []string{"$preprocessor"},
		},
		"preprocessor")
)

func init() {
	pctx.SourcePathVariable("versionerCmd", "prebuilts/clang-tools/${config.HostPrebuiltTag}/bin/versioner")
}

// Returns the NDK base include path for use with sdk_version current. Usable with -I.
func getCurrentIncludePath(ctx android.ModuleContext) android.InstallPath {
	return getNdkSysrootBase(ctx).Join(ctx, "usr/include")
}

type headerProperties struct {
	// Base directory of the headers being installed. As an example:
	//
	// ndk_headers {
	//     name: "foo",
	//     from: "include",
	//     to: "",
	//     srcs: ["include/foo/bar/baz.h"],
	// }
	//
	// Will install $SYSROOT/usr/include/foo/bar/baz.h. If `from` were instead
	// "include/foo", it would have installed $SYSROOT/usr/include/bar/baz.h.
	From *string

	// Install path within the sysroot. This is relative to usr/include.
	To *string

	// List of headers to install. Glob compatible. Common case is "include/**/*.h".
	Srcs []string `android:"path"`

	// Source paths that should be excluded from the srcs glob.
	Exclude_srcs []string `android:"path"`

	// Path to the NOTICE file associated with the headers.
	License *string `android:"path"`
}

type headerModule struct {
	android.ModuleBase

	properties headerProperties

	installPaths android.Paths
	licensePath  android.Path
}

func getHeaderInstallDir(ctx android.ModuleContext, header android.Path, from string,
	to string) android.InstallPath {
	// Output path is the sysroot base + "usr/include" + to directory + directory component
	// of the file without the leading from directory stripped.
	//
	// Given:
	// sysroot base = "ndk/sysroot"
	// from = "include/foo"
	// to = "bar"
	// header = "include/foo/woodly/doodly.h"
	// output path = "ndk/sysroot/usr/include/bar/woodly/doodly.h"

	// full/platform/path/to/include/foo
	fullFromPath := android.PathForModuleSrc(ctx, from)

	// full/platform/path/to/include/foo/woodly
	headerDir := filepath.Dir(header.String())

	// woodly
	strippedHeaderDir, err := filepath.Rel(fullFromPath.String(), headerDir)
	if err != nil {
		ctx.ModuleErrorf("filepath.Rel(%q, %q) failed: %s", headerDir,
			fullFromPath.String(), err)
	}

	// full/platform/path/to/sysroot/usr/include/bar/woodly
	installDir := getCurrentIncludePath(ctx).Join(ctx, to, strippedHeaderDir)

	// full/platform/path/to/sysroot/usr/include/bar/woodly/doodly.h
	return installDir
}

func (m *headerModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	if String(m.properties.License) == "" {
		ctx.PropertyErrorf("license", "field is required")
	}

	m.licensePath = android.PathForModuleSrc(ctx, String(m.properties.License))

	srcFiles := android.PathsForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)
	for _, header := range srcFiles {
		installDir := getHeaderInstallDir(ctx, header, String(m.properties.From),
			String(m.properties.To))
		installedPath := ctx.InstallFile(installDir, header.Base(), header)
		installPath := installDir.Join(ctx, header.Base())
		if installPath != installedPath {
			panic(fmt.Sprintf(
				"expected header install path (%q) not equal to actual install path %q",
				installPath, installedPath))
		}
		m.installPaths = append(m.installPaths, installPath)
	}

	if len(m.installPaths) == 0 {
		ctx.ModuleErrorf("srcs %q matched zero files", m.properties.Srcs)
	}
}

// ndk_headers installs the sets of ndk headers defined in the srcs property
// to the sysroot base + "usr/include" + to directory + directory component.
// ndk_headers requires the license file to be specified. Example:
//
//	Given:
//	sysroot base = "ndk/sysroot"
//	from = "include/foo"
//	to = "bar"
//	header = "include/foo/woodly/doodly.h"
//	output path = "ndk/sysroot/usr/include/bar/woodly/doodly.h"
func ndkHeadersFactory() android.Module {
	module := &headerModule{}
	module.AddProperties(&module.properties)
	android.InitAndroidModule(module)
	return module
}

type versionedHeaderProperties struct {
	// Base directory of the headers being installed. As an example:
	//
	// versioned_ndk_headers {
	//     name: "foo",
	//     from: "include",
	//     to: "",
	// }
	//
	// Will install $SYSROOT/usr/include/foo/bar/baz.h. If `from` were instead
	// "include/foo", it would have installed $SYSROOT/usr/include/bar/baz.h.
	From *string

	// Install path within the sysroot. This is relative to usr/include.
	To *string

	// Path to the NOTICE file associated with the headers.
	License *string
}

// Like ndk_headers, but preprocesses the headers with the bionic versioner:
// https://android.googlesource.com/platform/bionic/+/master/tools/versioner/README.md.
//
// Unlike ndk_headers, we don't operate on a list of sources but rather a whole directory, the
// module does not have the srcs property, and operates on a full directory (the `from` property).
//
// Note that this is really only built to handle bionic/libc/include.
type versionedHeaderModule struct {
	android.ModuleBase

	properties versionedHeaderProperties

	installPaths android.Paths
	licensePath  android.Path
}

// Return the glob pattern to find all .h files beneath `dir`
func headerGlobPattern(dir string) string {
	return filepath.Join(dir, "**", "*.h")
}

func (m *versionedHeaderModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	if String(m.properties.License) == "" {
		ctx.PropertyErrorf("license", "field is required")
	}

	m.licensePath = android.PathForModuleSrc(ctx, String(m.properties.License))

	fromSrcPath := android.PathForModuleSrc(ctx, String(m.properties.From))
	toOutputPath := getCurrentIncludePath(ctx).Join(ctx, String(m.properties.To))
	srcFiles := ctx.GlobFiles(headerGlobPattern(fromSrcPath.String()), nil)
	var installPaths []android.WritablePath
	for _, header := range srcFiles {
		installDir := getHeaderInstallDir(ctx, header, String(m.properties.From), String(m.properties.To))
		installPath := installDir.Join(ctx, header.Base())
		installPaths = append(installPaths, installPath)
		m.installPaths = append(m.installPaths, installPath)
	}

	if len(m.installPaths) == 0 {
		ctx.ModuleErrorf("glob %q matched zero files", String(m.properties.From))
	}

	processHeadersWithVersioner(ctx, fromSrcPath, toOutputPath, srcFiles, installPaths)
}

func processHeadersWithVersioner(ctx android.ModuleContext, srcDir, outDir android.Path,
	srcFiles android.Paths, installPaths []android.WritablePath) android.Path {
	// The versioner depends on a dependencies directory to simplify determining include paths
	// when parsing headers. This directory contains architecture specific directories as well
	// as a common directory, each of which contains symlinks to the actually directories to
	// be included.
	//
	// ctx.Glob doesn't follow symlinks, so we need to do this ourselves so we correctly
	// depend on these headers.
	// TODO(http://b/35673191): Update the versioner to use a --sysroot.
	depsPath := android.PathForSource(ctx, "bionic/libc/versioner-dependencies")
	depsGlob := ctx.Glob(filepath.Join(depsPath.String(), "**/*"), nil)
	for i, path := range depsGlob {
		if ctx.IsSymlink(path) {
			dest := ctx.Readlink(path)
			// Additional .. to account for the symlink itself.
			depsGlob[i] = android.PathForSource(
				ctx, filepath.Clean(filepath.Join(path.String(), "..", dest)))
		}
	}

	timestampFile := android.PathForModuleOut(ctx, "versioner.timestamp")
	ctx.Build(pctx, android.BuildParams{
		Rule:            versionBionicHeaders,
		Description:     "versioner preprocess " + srcDir.Rel(),
		Output:          timestampFile,
		Implicits:       append(srcFiles, depsGlob...),
		ImplicitOutputs: installPaths,
		Args: map[string]string{
			"depsPath": depsPath.String(),
			"srcDir":   srcDir.String(),
			"outDir":   outDir.String(),
		},
	})

	return timestampFile
}

// versioned_ndk_headers preprocesses the headers with the bionic versioner:
// https://android.googlesource.com/platform/bionic/+/master/tools/versioner/README.md.
// Unlike the ndk_headers soong module, versioned_ndk_headers operates on a
// directory level specified in `from` property. This is only used to process
// the bionic/libc/include directory.
func versionedNdkHeadersFactory() android.Module {
	module := &versionedHeaderModule{}

	module.AddProperties(&module.properties)

	android.InitAndroidModule(module)

	return module
}

// preprocessed_ndk_header {
//
//	name: "foo",
//	preprocessor: "foo.sh",
//	srcs: [...],
//	to: "android",
//
// }
//
// Will invoke the preprocessor as:
//
//	$preprocessor -o $SYSROOT/usr/include/android/needs_preproc.h $src
//
// For each src in srcs.
type preprocessedHeadersProperties struct {
	// The preprocessor to run. Must be a program inside the source directory
	// with no dependencies.
	Preprocessor *string

	// Source path to the files to be preprocessed.
	Srcs []string

	// Source paths that should be excluded from the srcs glob.
	Exclude_srcs []string

	// Install path within the sysroot. This is relative to usr/include.
	To *string

	// Path to the NOTICE file associated with the headers.
	License *string
}

type preprocessedHeadersModule struct {
	android.ModuleBase

	properties preprocessedHeadersProperties

	installPaths android.Paths
	licensePath  android.Path
}

func (m *preprocessedHeadersModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	if String(m.properties.License) == "" {
		ctx.PropertyErrorf("license", "field is required")
	}

	preprocessor := android.PathForModuleSrc(ctx, String(m.properties.Preprocessor))
	m.licensePath = android.PathForModuleSrc(ctx, String(m.properties.License))

	srcFiles := android.PathsForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)
	installDir := getCurrentIncludePath(ctx).Join(ctx, String(m.properties.To))
	for _, src := range srcFiles {
		installPath := installDir.Join(ctx, src.Base())
		m.installPaths = append(m.installPaths, installPath)

		ctx.Build(pctx, android.BuildParams{
			Rule:        preprocessNdkHeader,
			Description: "preprocess " + src.Rel(),
			Input:       src,
			Output:      installPath,
			Args: map[string]string{
				"preprocessor": preprocessor.String(),
			},
		})
	}

	if len(m.installPaths) == 0 {
		ctx.ModuleErrorf("srcs %q matched zero files", m.properties.Srcs)
	}
}

// preprocessed_ndk_headers preprocesses all the ndk headers listed in the srcs
// property by executing the command defined in the preprocessor property.
func preprocessedNdkHeadersFactory() android.Module {
	module := &preprocessedHeadersModule{}

	module.AddProperties(&module.properties)

	android.InitAndroidModule(module)

	return module
}
