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

	"github.com/google/blueprint"

	"android/soong/glob"
)

// This file supports globbing source files in Blueprints files.
//
// The build.ninja file needs to be regenerated any time a file matching the glob is added
// or removed.  The naive solution is to have the build.ninja file depend on all the
// traversed directories, but this will cause the regeneration step to run every time a
// non-matching file is added to a traversed directory, including backup files created by
// editors.
//
// The solution implemented here optimizes out regenerations when the directory modifications
// don't match the glob by having the build.ninja file depend on an intermedate file that
// is only updated when a file matching the glob is added or removed.  The intermediate file
// depends on the traversed directories via a depfile.  The depfile is used to avoid build
// errors if a directory is deleted - a direct dependency on the deleted directory would result
// in a build failure with a "missing and no known rule to make it" error.

var (
	globCmd = filepath.Join("${bootstrap.ToolDir}", "soong_glob")

	// globRule rule traverses directories to produce a list of files that match $glob
	// and writes it to $out if it has changed, and writes the directories to $out.d
	globRule = pctx.AndroidStaticRule("globRule",
		blueprint.RuleParams{
			Command:     fmt.Sprintf(`%s -o $out $excludes "$glob"`, globCmd),
			CommandDeps: []string{globCmd},
			Description: "glob $glob",

			Restat:  true,
			Deps:    blueprint.DepsGCC,
			Depfile: "$out.d",
		},
		"glob", "excludes")
)

func hasGlob(in []string) bool {
	for _, s := range in {
		if glob.IsGlob(s) {
			return true
		}
	}

	return false
}

// The subset of ModuleContext and SingletonContext needed by Glob
type globContext interface {
	Build(pctx blueprint.PackageContext, params blueprint.BuildParams)
	AddNinjaFileDeps(deps ...string)
}

func Glob(ctx globContext, outDir string, globPattern string, excludes []string) ([]string, error) {
	fileListFile := filepath.Join(outDir, "glob", globToString(globPattern)+".glob")
	depFile := fileListFile + ".d"

	// Get a globbed file list, and write out fileListFile and depFile
	files, err := glob.GlobWithDepFile(globPattern, fileListFile, depFile, excludes)
	if err != nil {
		return nil, err
	}

	GlobRule(ctx, globPattern, excludes, fileListFile, depFile)

	// Make build.ninja depend on the fileListFile
	ctx.AddNinjaFileDeps(fileListFile)

	return files, nil
}

func GlobRule(ctx globContext, globPattern string, excludes []string,
	fileListFile, depFile string) {

	// Create a rule to rebuild fileListFile if a directory in depFile changes.  fileListFile
	// will only be rewritten if it has changed, preventing unnecesary build.ninja regenerations.
	ctx.Build(pctx, blueprint.BuildParams{
		Rule:    globRule,
		Outputs: []string{fileListFile},
		Args: map[string]string{
			"glob":     globPattern,
			"excludes": JoinWithPrefixAndQuote(excludes, "-e "),
		},
	})
}

func globToString(glob string) string {
	ret := ""
	for _, c := range glob {
		if c >= 'a' && c <= 'z' ||
			c >= 'A' && c <= 'Z' ||
			c >= '0' && c <= '9' ||
			c == '_' || c == '-' || c == '/' {
			ret += string(c)
		}
	}

	return ret
}
