// 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 $cpPreserveSymlinks $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())
}
