// Copyright 2020 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 bp2build

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"android/soong/android"
	"android/soong/bazel"
	"android/soong/shared"
	"android/soong/starlark_import"
)

func deleteFilesExcept(ctx *CodegenContext, rootOutputPath android.OutputPath, except []BazelFile) {
	// Delete files that should no longer be present.
	bp2buildDirAbs := shared.JoinPath(ctx.topDir, rootOutputPath.String())

	filesToDelete := make(map[string]struct{})
	err := filepath.Walk(bp2buildDirAbs,
		func(path string, info os.FileInfo, err error) error {
			if err != nil {
				return err
			}
			if !info.IsDir() {
				relPath, err := filepath.Rel(bp2buildDirAbs, path)
				if err != nil {
					return err
				}
				filesToDelete[relPath] = struct{}{}
			}
			return nil
		})
	if err != nil {
		fmt.Printf("ERROR reading %s: %s", bp2buildDirAbs, err)
		os.Exit(1)
	}

	for _, bazelFile := range except {
		filePath := filepath.Join(bazelFile.Dir, bazelFile.Basename)
		delete(filesToDelete, filePath)
	}
	for f, _ := range filesToDelete {
		absPath := shared.JoinPath(bp2buildDirAbs, f)
		if err := os.RemoveAll(absPath); err != nil {
			fmt.Printf("ERROR deleting %s: %s", absPath, err)
			os.Exit(1)
		}
	}
}

// Codegen is the backend of bp2build. The code generator is responsible for
// writing .bzl files that are equivalent to Android.bp files that are capable
// of being built with Bazel.
func Codegen(ctx *CodegenContext) *CodegenMetrics {
	ctx.Context().BeginEvent("Codegen")
	defer ctx.Context().EndEvent("Codegen")
	// This directory stores BUILD files that could be eventually checked-in.
	bp2buildDir := android.PathForOutput(ctx, "bp2build")

	res, errs := GenerateBazelTargets(ctx, true)
	if len(errs) > 0 {
		errMsgs := make([]string, len(errs))
		for i, err := range errs {
			errMsgs[i] = fmt.Sprintf("%q", err)
		}
		fmt.Printf("ERROR: Encountered %d error(s): \nERROR: %s", len(errs), strings.Join(errMsgs, "\n"))
		os.Exit(1)
	}
	var bp2buildFiles []BazelFile
	ctx.Context().EventHandler.Do("CreateBazelFile", func() {
		bp2buildFiles = CreateBazelFiles(nil, res.buildFileToTargets, ctx.mode)
	})
	injectionFiles, additionalBp2buildFiles, err := CreateSoongInjectionDirFiles(ctx, res.metrics)
	if err != nil {
		fmt.Printf("%s\n", err.Error())
		os.Exit(1)
	}
	bp2buildFiles = append(bp2buildFiles, additionalBp2buildFiles...)
	writeFiles(ctx, bp2buildDir, bp2buildFiles)
	// Delete files under the bp2build root which weren't just written. An
	// alternative would have been to delete the whole directory and write these
	// files. However, this would regenerate files which were otherwise unchanged
	// since the last bp2build run, which would have negative incremental
	// performance implications.
	deleteFilesExcept(ctx, bp2buildDir, bp2buildFiles)

	writeFiles(ctx, android.PathForOutput(ctx, bazel.SoongInjectionDirName), injectionFiles)
	starlarkDeps, err := starlark_import.GetNinjaDeps()
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", err)
		os.Exit(1)
	}
	ctx.AddNinjaFileDeps(starlarkDeps...)
	return &res.metrics
}

// Wrapper function that will be responsible for all files in soong_injection directory
// This includes
// 1. config value(s) that are hardcoded in Soong
// 2. product_config variables
func CreateSoongInjectionDirFiles(ctx *CodegenContext, metrics CodegenMetrics) ([]BazelFile, []BazelFile, error) {
	var ret []BazelFile

	productConfigInjectionFiles, productConfigBp2BuildDirFiles, err := CreateProductConfigFiles(ctx, metrics)
	if err != nil {
		return nil, nil, err
	}
	ret = append(ret, productConfigInjectionFiles...)
	injectionFiles, err := soongInjectionFiles(ctx.Config(), metrics)
	if err != nil {
		return nil, nil, err
	}
	ret = append(injectionFiles, ret...)
	return ret, productConfigBp2BuildDirFiles, nil
}

// Get the output directory and create it if it doesn't exist.
func getOrCreateOutputDir(outputDir android.OutputPath, ctx android.PathContext, dir string) android.OutputPath {
	dirPath := outputDir.Join(ctx, dir)
	if err := android.CreateOutputDirIfNonexistent(dirPath, os.ModePerm); err != nil {
		fmt.Printf("ERROR: path %s: %s", dirPath, err.Error())
	}
	return dirPath
}

// writeFiles materializes a list of BazelFile rooted at outputDir.
func writeFiles(ctx android.PathContext, outputDir android.OutputPath, files []BazelFile) {
	for _, f := range files {
		p := getOrCreateOutputDir(outputDir, ctx, f.Dir).Join(ctx, f.Basename)
		if err := writeFile(p, f.Contents); err != nil {
			panic(fmt.Errorf("Failed to write %q (dir %q) due to %q", f.Basename, f.Dir, err))
		}
	}
}

func writeFile(pathToFile android.OutputPath, content string) error {
	// These files are made editable to allow users to modify and iterate on them
	// in the source tree.
	return android.WriteFileToOutputDir(pathToFile, []byte(content), 0644)
}
