// 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.BinDir}", "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.StaticRule("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
}
