// 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"
	"os"
	"path/filepath"
	"strings"

	"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.OutputPath {
	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

	// Source paths that should be excluded from the srcs glob.
	Exclude_srcs []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 headerModule struct {
	android.ModuleBase

	properties headerProperties

	installPaths android.Paths
	licensePath  android.ModuleSrcPath
}

func getHeaderInstallDir(ctx android.ModuleContext, header android.Path, from string,
	to string) android.OutputPath {
	// 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))

	// When generating NDK prebuilts, skip installing MIPS headers,
	// but keep them when doing regular platform build.
	// Ndk_abis property is only set to true with build/soong/scripts/build-ndk-prebuilts.sh
	// TODO: Revert this once MIPS is supported in NDK again.
	if ctx.Config().NdkAbis() && strings.Contains(ctx.ModuleName(), "mips") {
		return
	}

	srcFiles := ctx.ExpandSources(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)
	}
}

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.ModuleSrcPath
}

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 {
		fileInfo, err := os.Lstat(path.String())
		if err != nil {
			ctx.ModuleErrorf("os.Lstat(%q) failed: %s", path.String, err)
		}
		if fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
			dest, err := os.Readlink(path.String())
			if err != nil {
				ctx.ModuleErrorf("os.Readlink(%q) failed: %s",
					path.String, err)
			}
			// 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
}

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.ModuleSrcPath
}

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 := ctx.ExpandSources(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)
	}
}

func preprocessedNdkHeadersFactory() android.Module {
	module := &preprocessedHeadersModule{}

	module.AddProperties(&module.properties)

	android.InitAndroidModule(module)

	return module
}
