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

	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()
	})
}

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())
}
