// Copyright 2015 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 android

import (
	"fmt"
	"strings"
	"testing"

	"github.com/google/blueprint"
	"github.com/google/blueprint/bootstrap"
	"github.com/google/blueprint/proptools"
)

var (
	pctx         = NewPackageContext("android/soong/android")
	exportedVars = NewExportedVariables(pctx)

	cpPreserveSymlinks = pctx.VariableConfigMethod("cpPreserveSymlinks",
		Config.CpPreserveSymlinksFlags)

	// A phony rule that is not the built-in Ninja phony rule.  The built-in
	// phony rule has special behavior that is sometimes not desired.  See the
	// Ninja docs for more details.
	Phony = pctx.AndroidStaticRule("Phony",
		blueprint.RuleParams{
			Command:     "# phony $out",
			Description: "phony $out",
		})

	// GeneratedFile is a rule for indicating that a given file was generated
	// while running soong.  This allows the file to be cleaned up if it ever
	// stops being generated by soong.
	GeneratedFile = pctx.AndroidStaticRule("GeneratedFile",
		blueprint.RuleParams{
			Command:     "# generated $out",
			Description: "generated $out",
			Generator:   true,
		})

	// A copy rule.
	Cp = pctx.AndroidStaticRule("Cp",
		blueprint.RuleParams{
			Command:     "rm -f $out && cp $cpPreserveSymlinks $cpFlags $in $out$extraCmds",
			Description: "cp $out",
		},
		"cpFlags", "extraCmds")

	// A copy rule that only updates the output if it changed.
	CpIfChanged = pctx.AndroidStaticRule("CpIfChanged",
		blueprint.RuleParams{
			Command:     "if ! cmp -s $in $out; then cp $in $out; fi",
			Description: "cp if changed $out",
			Restat:      true,
		},
		"cpFlags")

	CpExecutable = pctx.AndroidStaticRule("CpExecutable",
		blueprint.RuleParams{
			Command:     "rm -f $out && cp $cpFlags $in $out && chmod +x $out$extraCmds",
			Description: "cp $out",
		},
		"cpFlags", "extraCmds")

	// A timestamp touch rule.
	Touch = pctx.AndroidStaticRule("Touch",
		blueprint.RuleParams{
			Command:     "touch $out",
			Description: "touch $out",
		})

	// A symlink rule.
	Symlink = pctx.AndroidStaticRule("Symlink",
		blueprint.RuleParams{
			Command:        "rm -f $out && ln -f -s $fromPath $out",
			Description:    "symlink $out",
			SymlinkOutputs: []string{"$out"},
		},
		"fromPath")

	ErrorRule = pctx.AndroidStaticRule("Error",
		blueprint.RuleParams{
			Command:     `echo "$error" && false`,
			Description: "error building $out",
		},
		"error")

	Cat = pctx.AndroidStaticRule("Cat",
		blueprint.RuleParams{
			Command:     "cat $in > $out",
			Description: "concatenate licenses $out",
		})

	// ubuntu 14.04 offcially use dash for /bin/sh, and its builtin echo command
	// doesn't support -e option. Therefore we force to use /bin/bash when writing out
	// content to file.
	writeFile = pctx.AndroidStaticRule("writeFile",
		blueprint.RuleParams{
			Command:     `/bin/bash -c 'echo -e -n "$$0" > $out' $content`,
			Description: "writing file $out",
		},
		"content")

	// Used only when USE_GOMA=true is set, to restrict non-goma jobs to the local parallelism value
	localPool = blueprint.NewBuiltinPool("local_pool")

	// Used only by RuleBuilder to identify remoteable rules. Does not actually get created in ninja.
	remotePool = blueprint.NewBuiltinPool("remote_pool")

	// Used for processes that need significant RAM to ensure there are not too many running in parallel.
	highmemPool = blueprint.NewBuiltinPool("highmem_pool")
)

func init() {
	pctx.Import("github.com/google/blueprint/bootstrap")

	pctx.VariableFunc("RBEWrapper", func(ctx PackageVarContext) string {
		return ctx.Config().RBEWrapper()
	})

	exportedVars.ExportStringList("NeverAllowNotInIncludeDir", neverallowNotInIncludeDir)
	exportedVars.ExportStringList("NeverAllowNoUseIncludeDir", neverallowNoUseIncludeDir)
}

func BazelCcToolchainVars(config Config) string {
	return BazelToolchainVars(config, exportedVars)
}

var (
	// echoEscaper escapes a string such that passing it to "echo -e" will produce the input value.
	echoEscaper = strings.NewReplacer(
		`\`, `\\`, // First escape existing backslashes so they aren't interpreted by `echo -e`.
		"\n", `\n`, // Then replace newlines with \n
	)

	// echoEscaper reverses echoEscaper.
	echoUnescaper = strings.NewReplacer(
		`\n`, "\n",
		`\\`, `\`,
	)

	// shellUnescaper reverses the replacer in proptools.ShellEscape
	shellUnescaper = strings.NewReplacer(`'\''`, `'`)
)

func buildWriteFileRule(ctx BuilderContext, outputFile WritablePath, content string) {
	content = echoEscaper.Replace(content)
	content = proptools.NinjaEscape(proptools.ShellEscapeIncludingSpaces(content))
	if content == "" {
		content = "''"
	}
	ctx.Build(pctx, BuildParams{
		Rule:        writeFile,
		Output:      outputFile,
		Description: "write " + outputFile.Base(),
		Args: map[string]string{
			"content": content,
		},
	})
}

// WriteFileRule creates a ninja rule to write contents to a file.  The contents will be escaped
// so that the file contains exactly the contents passed to the function, plus a trailing newline.
func WriteFileRule(ctx BuilderContext, outputFile WritablePath, content string) {
	// This is MAX_ARG_STRLEN subtracted with some safety to account for shell escapes
	const SHARD_SIZE = 131072 - 10000

	content += "\n"
	if len(content) > SHARD_SIZE {
		var chunks WritablePaths
		for i, c := range ShardString(content, SHARD_SIZE) {
			tempPath := outputFile.ReplaceExtension(ctx, fmt.Sprintf("%s.%d", outputFile.Ext(), i))
			buildWriteFileRule(ctx, tempPath, c)
			chunks = append(chunks, tempPath)
		}
		ctx.Build(pctx, BuildParams{
			Rule:        Cat,
			Inputs:      chunks.Paths(),
			Output:      outputFile,
			Description: "Merging to " + outputFile.Base(),
		})
		return
	}
	buildWriteFileRule(ctx, outputFile, content)
}

func CatFileRule(ctx BuilderContext, paths Paths, outputFile WritablePath) {
	ctx.Build(pctx, BuildParams{
		Rule:        Cat,
		Inputs:      paths,
		Output:      outputFile,
		Description: "combine files to " + outputFile.Base(),
	})
}

// shellUnescape reverses proptools.ShellEscape
func shellUnescape(s string) string {
	// Remove leading and trailing quotes if present
	if len(s) >= 2 && s[0] == '\'' {
		s = s[1 : len(s)-1]
	}
	s = shellUnescaper.Replace(s)
	return s
}

// ContentFromFileRuleForTests returns the content that was passed to a WriteFileRule for use
// in tests.
func ContentFromFileRuleForTests(t *testing.T, params TestingBuildParams) string {
	t.Helper()
	if g, w := params.Rule, writeFile; g != w {
		t.Errorf("expected params.Rule to be %q, was %q", w, g)
		return ""
	}

	content := params.Args["content"]
	content = shellUnescape(content)
	content = echoUnescaper.Replace(content)

	return content
}

// GlobToListFileRule creates a rule that writes a list of files matching a pattern to a file.
func GlobToListFileRule(ctx ModuleContext, pattern string, excludes []string, file WritablePath) {
	bootstrap.GlobFile(ctx.blueprintModuleContext(), pattern, excludes, file.String())
}
