// 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"`

	// True if this API is not yet ready to be shipped in the NDK. It will be
	// available in the platform for testing, but will be excluded from the
	// sysroot provided to the NDK proper.
	Draft bool
}

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

	// True if this API is not yet ready to be shipped in the NDK. It will be
	// available in the platform for testing, but will be excluded from the
	// sysroot provided to the NDK proper.
	Draft bool
}

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

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(filepath.Join(fromSrcPath.String(), "**/*.h"), 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

	// True if this API is not yet ready to be shipped in the NDK. It will be
	// available in the platform for testing, but will be excluded from the
	// sysroot provided to the NDK proper.
	Draft bool
}

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
}
