// 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",
			Description: "cp $out",
		},
		"cpFlags")

	// 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",
			Description: "cp $out",
		},
		"cpFlags")

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