// Copyright 2018 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 cc

import (
	"encoding/json"
	"log"
	"os"
	"path/filepath"
	"strings"

	"android/soong/android"
)

// This singleton generates a compile_commands.json file. It does so for each
// blueprint Android.bp resulting in a cc.Module when either make, mm, mma, mmm
// or mmma is called. It will only create a single compile_commands.json file
// at ${OUT_DIR}/soong/development/ide/compdb/compile_commands.json. It will also symlink it
// to ${SOONG_LINK_COMPDB_TO} if set. In general this should be created by running
// make SOONG_GEN_COMPDB=1 nothing to get all targets.

func init() {
	android.RegisterSingletonType("compdb_generator", compDBGeneratorSingleton)
}

func compDBGeneratorSingleton() android.Singleton {
	return &compdbGeneratorSingleton{}
}

type compdbGeneratorSingleton struct{}

const (
	compdbFilename                = "compile_commands.json"
	compdbOutputProjectsDirectory = "development/ide/compdb"

	// Environment variables used to modify behavior of this singleton.
	envVariableGenerateCompdb          = "SOONG_GEN_COMPDB"
	envVariableGenerateCompdbDebugInfo = "SOONG_GEN_COMPDB_DEBUG"
	envVariableCompdbLink              = "SOONG_LINK_COMPDB_TO"
)

// A compdb entry. The compile_commands.json file is a list of these.
type compDbEntry struct {
	Directory string   `json:"directory"`
	Arguments []string `json:"arguments"`
	File      string   `json:"file"`
	Output    string   `json:"output,omitempty"`
}

func (c *compdbGeneratorSingleton) GenerateBuildActions(ctx android.SingletonContext) {
	if !ctx.Config().IsEnvTrue(envVariableGenerateCompdb) {
		return
	}

	// Instruct the generator to indent the json file for easier debugging.
	outputCompdbDebugInfo := ctx.Config().IsEnvTrue(envVariableGenerateCompdbDebugInfo)

	// We only want one entry per file. We don't care what module/isa it's from
	m := make(map[string]compDbEntry)
	ctx.VisitAllModules(func(module android.Module) {
		if ccModule, ok := module.(*Module); ok {
			if compiledModule, ok := ccModule.compiler.(CompiledInterface); ok {
				generateCompdbProject(compiledModule, ctx, ccModule, m)
			}
		}
	})

	// Create the output file.
	dir := android.PathForOutput(ctx, compdbOutputProjectsDirectory)
	os.MkdirAll(filepath.Join(android.AbsSrcDirForExistingUseCases(), dir.String()), 0777)
	compDBFile := dir.Join(ctx, compdbFilename)
	f, err := os.Create(filepath.Join(android.AbsSrcDirForExistingUseCases(), compDBFile.String()))
	if err != nil {
		log.Fatalf("Could not create file %s: %s", compDBFile, err)
	}
	defer f.Close()

	v := make([]compDbEntry, 0, len(m))

	for _, value := range m {
		v = append(v, value)
	}
	var dat []byte
	if outputCompdbDebugInfo {
		dat, err = json.MarshalIndent(v, "", " ")
	} else {
		dat, err = json.Marshal(v)
	}
	if err != nil {
		log.Fatalf("Failed to marshal: %s", err)
	}
	f.Write(dat)

	if finalLinkDir := ctx.Config().Getenv(envVariableCompdbLink); finalLinkDir != "" {
		finalLinkPath := filepath.Join(finalLinkDir, compdbFilename)
		os.Remove(finalLinkPath)
		if err := os.Symlink(compDBFile.String(), finalLinkPath); err != nil {
			log.Fatalf("Unable to symlink %s to %s: %s", compDBFile, finalLinkPath, err)
		}
	}
}

func expandAllVars(ctx android.SingletonContext, args []string) []string {
	var out []string
	for _, arg := range args {
		if arg != "" {
			if val, err := evalAndSplitVariable(ctx, arg); err == nil {
				out = append(out, val...)
			} else {
				out = append(out, arg)
			}
		}
	}
	return out
}

func getArguments(src android.Path, ctx android.SingletonContext, ccModule *Module, ccPath string, cxxPath string) []string {
	var args []string
	isCpp := false
	isAsm := false
	// TODO It would be better to ask soong for the types here.
	var clangPath string
	switch src.Ext() {
	case ".S", ".s", ".asm":
		isAsm = true
		isCpp = false
		clangPath = ccPath
	case ".c":
		isAsm = false
		isCpp = false
		clangPath = ccPath
	case ".cpp", ".cc", ".cxx", ".mm":
		isAsm = false
		isCpp = true
		clangPath = cxxPath
	default:
		log.Print("Unknown file extension " + src.Ext() + " on file " + src.String())
		isAsm = true
		isCpp = false
		clangPath = ccPath
	}
	args = append(args, clangPath)
	args = append(args, expandAllVars(ctx, ccModule.flags.Global.CommonFlags)...)
	args = append(args, expandAllVars(ctx, ccModule.flags.Local.CommonFlags)...)
	args = append(args, expandAllVars(ctx, ccModule.flags.Global.CFlags)...)
	args = append(args, expandAllVars(ctx, ccModule.flags.Local.CFlags)...)
	if isCpp {
		args = append(args, expandAllVars(ctx, ccModule.flags.Global.CppFlags)...)
		args = append(args, expandAllVars(ctx, ccModule.flags.Local.CppFlags)...)
	} else if !isAsm {
		args = append(args, expandAllVars(ctx, ccModule.flags.Global.ConlyFlags)...)
		args = append(args, expandAllVars(ctx, ccModule.flags.Local.ConlyFlags)...)
	}
	args = append(args, expandAllVars(ctx, ccModule.flags.SystemIncludeFlags)...)
	args = append(args, src.String())
	return args
}

func generateCompdbProject(compiledModule CompiledInterface, ctx android.SingletonContext, ccModule *Module, builds map[string]compDbEntry) {
	srcs := compiledModule.Srcs()
	if len(srcs) == 0 {
		return
	}

	pathToCC, err := ctx.Eval(pctx, "${config.ClangBin}")
	ccPath := "/bin/false"
	cxxPath := "/bin/false"
	if err == nil {
		ccPath = filepath.Join(pathToCC, "clang")
		cxxPath = filepath.Join(pathToCC, "clang++")
	}
	for _, src := range srcs {
		if _, ok := builds[src.String()]; !ok {
			builds[src.String()] = compDbEntry{
				Directory: android.AbsSrcDirForExistingUseCases(),
				Arguments: getArguments(src, ctx, ccModule, ccPath, cxxPath),
				File:      src.String(),
			}
		}
	}
}

func evalAndSplitVariable(ctx android.SingletonContext, str string) ([]string, error) {
	evaluated, err := ctx.Eval(pctx, str)
	if err == nil {
		return strings.Fields(evaluated), nil
	}
	return []string{""}, err
}
