// Copyright 2022 The Android Open Source Project
//
// 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 main

import (
	"bufio"
	"context"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"runtime"
	"strings"
	"time"

	"tools/treble/build/report/app"
	"tools/treble/build/report/local"
	"tools/treble/build/report/report"
)

type Build interface {
	Build(ctx context.Context, target string) *app.BuildCmdResult
}

type tool interface {
	Run(ctx context.Context, rtx *report.Context, rsp *response) error
	PrintText(w io.Writer, rsp *response, verbose bool)
}
type repoFlags []app.ProjectCommit

func (r *repoFlags) Set(value string) error {
	commit := app.ProjectCommit{}
	items := strings.Split(value, ":")
	if len(items) > 2 {
		return (errors.New("Invalid repo value expected (proj:sha) format"))
	}
	commit.Project = items[0]
	if len(items) > 1 {
		commit.Revision = items[1]
	}
	*r = append(*r, commit)
	return nil
}
func (r *repoFlags) String() string {
	items := []string{}
	for _, fl := range *r {
		items = append(items, fmt.Sprintf("%s:%s", fl.Project, fl.Revision))
	}
	return strings.Join(items, " ")
}

var (
	// Common flags
	ninjaDbPtr          = flag.String("ninja", local.DefNinjaDb(), "Set the .ninja file to use when building metrics")
	ninjaExcPtr         = flag.String("ninja_cmd", local.DefNinjaExc(), "Set the ninja executable")
	ninjaTimeoutStr     = flag.String("ninja_timeout", local.DefaultNinjaTimeout, "Default ninja timeout")
	buildTimeoutStr     = flag.String("build_timeout", local.DefaultNinjaBuildTimeout, "Default build timeout")
	manifestPtr         = flag.String("manifest", local.DefManifest(), "Set the location of the manifest file")
	upstreamPtr         = flag.String("upstream", "", "Upstream branch to compare files against")
	repoBasePtr         = flag.String("repo_base", local.DefRepoBase(), "Set the repo base directory")
	workerCountPtr      = flag.Int("worker_count", runtime.NumCPU(), "Number of worker routines")
	buildWorkerCountPtr = flag.Int("build_worker_count", local.MaxNinjaCliWorkers, "Number of build worker routines")
	clientServerPtr     = flag.Bool("client_server", false, "Run client server mode")
	buildPtr            = flag.Bool("build", false, "Build targets")
	jsonPtr             = flag.Bool("json", false, "Print json data")
	verbosePtr          = flag.Bool("v", false, "Print verbose text data")
	outputPtr           = flag.String("o", "", "Output to file")

	hostFlags  = flag.NewFlagSet("host", flag.ExitOnError)
	queryFlags = flag.NewFlagSet("query", flag.ExitOnError)
	pathsFlags = flag.NewFlagSet("paths", flag.ExitOnError)
)

// Add profiling data
type profTime struct {
	Description  string  `json:"description"`
	DurationSecs float64 `json:"duration"`
}

type commit struct {
	Project app.ProjectCommit `json:"project"`
	Commit  *app.GitCommit    `json:"commit"`
}

// Use one structure for output for now
type response struct {
	Commits    []commit              `json:"commits,omitempty"`
	Inputs     []string              `json:"files,omitempty"`
	BuildFiles []*app.BuildCmdResult `json:"build_files,omitempty"`
	Targets    []string              `json:"targets,omitempty"`
	Report     *app.Report           `json:"report,omitempty"`

	// Subcommand data
	Query *app.QueryResponse `json:"query,omitempty"`
	Paths []*app.BuildPath   `json:"build_paths,omitempty"`
	Host  *app.HostReport    `json:"host,omitempty"`

	// Profile data
	Profile []*profTime `json:"profile"`
}

func main() {
	startTime := time.Now()
	ctx := context.Background()
	rsp := &response{}

	var addProfileData = func(desc string) {
		rsp.Profile = append(rsp.Profile, &profTime{Description: desc, DurationSecs: time.Since(startTime).Seconds()})
		startTime = time.Now()
	}
	flag.Parse()

	ninjaTimeout, err := time.ParseDuration(*ninjaTimeoutStr)
	if err != nil {
		log.Fatalf("Invalid ninja timeout %s", *ninjaTimeoutStr)
	}

	buildTimeout, err := time.ParseDuration(*buildTimeoutStr)
	if err != nil {
		log.Fatalf("Invalid build timeout %s", *buildTimeoutStr)
	}

	subArgs := flag.Args()
	if len(subArgs) < 1 {
		// Nothing to do
		return
	}
	defBuildTarget := "droid"
	log.SetFlags(log.LstdFlags | log.Llongfile)

	ninja := local.NewNinjaCli(*ninjaExcPtr, *ninjaDbPtr, ninjaTimeout, buildTimeout, *clientServerPtr)

	if *clientServerPtr {
		go func() {
			ninjaServ := local.NewNinjaCli(*ninjaExcPtr, *ninjaDbPtr, ninjaTimeout, buildTimeout, false)
			ninjaServ.StartServer(ctx)
		}()
		if err := ninja.WaitForServer(ctx, 60); err != nil {
			log.Fatalf("Failed to connect to server")
		}
	}
	rtx := &report.Context{
		RepoBase:         *repoBasePtr,
		Repo:             &report.RepoMan{},
		Build:            ninja,
		Project:          local.NewGitCli(),
		WorkerCount:      *workerCountPtr,
		BuildWorkerCount: *buildWorkerCountPtr,
	}

	var subcommand tool
	var commits repoFlags

	switch subArgs[0] {
	case "host":
		hostToolPathPtr := hostFlags.String("hostbin", local.DefHostBinPath(), "Set the output directory for host tools")
		hostFlags.Parse(subArgs[1:])

		subcommand = &hostReport{toolPath: *hostToolPathPtr}
		rsp.Targets = hostFlags.Args()

	case "query":
		queryFlags.Var(&commits, "repo", "Repo:SHA to query")
		queryFlags.Parse(subArgs[1:])
		subcommand = &queryReport{}
		rsp.Targets = queryFlags.Args()

	case "paths":
		pathsFlags.Var(&commits, "repo", "Repo:SHA to build")
		singlePathPtr := pathsFlags.Bool("1", false, "Get single path to output target")
		pathsFlags.Parse(subArgs[1:])

		subcommand = &pathsReport{build_target: defBuildTarget, single: *singlePathPtr}

		rsp.Targets = pathsFlags.Args()

	default:
		rsp.Targets = subArgs
	}
	addProfileData("Init")
	rtx.ResolveProjectMap(ctx, *manifestPtr, *upstreamPtr)
	addProfileData("Project Map")

	// Resolve any commits
	if len(commits) > 0 {
		log.Printf("Resolving %s", commits.String())
		for _, c := range commits {
			commit := commit{Project: c}
			info, files, err := report.ResolveCommit(ctx, rtx, &c)
			if err != nil {
				log.Fatalf("Failed to resolve commit %s:%s", c.Project, c.Revision)
			}
			commit.Commit = info
			rsp.Commits = append(rsp.Commits, commit)

			// Add files to list of inputs
			rsp.Inputs = append(rsp.Inputs, files...)
		}
		addProfileData("Commit Resolution")
	}

	// Run any sub tools
	if subcommand != nil {
		if err := subcommand.Run(ctx, rtx, rsp); err != nil {
			log.Fatal(err)
		}
		addProfileData(subArgs[0])
	}

	buildErrors := 0
	if *buildPtr {
		for _, t := range rsp.Targets {
			log.Printf("Building %s\n", t)
			res := ninja.Build(ctx, t)
			addProfileData(fmt.Sprintf("Build %s", t))
			log.Printf("%s\n", res.Output)
			if res.Success != true {
				buildErrors++
			}
			rsp.BuildFiles = append(rsp.BuildFiles, res)
		}
	}

	// Generate report
	log.Printf("Generating report for targets %s", rsp.Targets)
	req := &app.ReportRequest{Targets: rsp.Targets}
	rsp.Report, err = report.RunReport(ctx, rtx, req)
	addProfileData("Report")
	if err != nil {
		log.Fatal(fmt.Sprintf("Report failure <%s>", err))
	}

	if *jsonPtr {
		b, _ := json.MarshalIndent(rsp, "", "\t")
		if *outputPtr == "" {
			os.Stdout.Write(b)
		} else {
			os.WriteFile(*outputPtr, b, 0644)
		}
	} else {
		if *outputPtr == "" {
			printTextReport(os.Stdout, subcommand, rsp, *verbosePtr)
		} else {
			file, err := os.Create(*outputPtr)
			if err != nil {
				log.Fatalf("Failed to create output file %s (%s)", *outputPtr, err)
			}
			w := bufio.NewWriter(file)
			printTextReport(w, subcommand, rsp, *verbosePtr)
			w.Flush()
		}

	}

	if buildErrors > 0 {
		log.Fatal(fmt.Sprintf("Failed to build %d targets", buildErrors))
	}
}

func printTextReport(w io.Writer, subcommand tool, rsp *response, verbose bool) {
	fmt.Fprintln(w, "Metric Report")
	if subcommand != nil {
		subcommand.PrintText(w, rsp, verbose)
	}

	if len(rsp.Commits) > 0 {
		fmt.Fprintln(w, "")
		fmt.Fprintln(w, "  Commit Results")
		for _, c := range rsp.Commits {
			fmt.Fprintf(w, "   %-120s : %s\n", c.Project.Project, c.Project.Revision)
			fmt.Fprintf(w, "       SHA   : %s\n", c.Commit.Sha)
			fmt.Fprintf(w, "       Files : \n")
			for _, f := range c.Commit.Files {
				fmt.Fprintf(w, "         %s  %s\n", f.Type.String(), f.Filename)
			}
		}
	}
	if len(rsp.BuildFiles) > 0 {
		fmt.Fprintln(w, "")
		fmt.Fprintln(w, "  Build Files")
		for _, b := range rsp.BuildFiles {
			fmt.Fprintf(w, "            %-120s : %t \n", b.Name, b.Success)
		}
	}

	targetPrint := func(target *app.BuildTarget) {
		fmt.Fprintf(w, "      %-20s       : %s\n", "Name", target.Name)
		fmt.Fprintf(w, "         %-20s    : %d\n", "Build Steps", target.Steps)
		fmt.Fprintf(w, "         %-20s        \n", "Inputs")
		fmt.Fprintf(w, "            %-20s : %d\n", "Files", target.FileCount)
		fmt.Fprintf(w, "            %-20s : %d\n", "Projects", len(target.Projects))
		fmt.Fprintln(w)
		for name, proj := range target.Projects {
			forkCount := 0
			for _, file := range proj.Files {
				if file.BranchDiff != nil {
					forkCount++
				}
			}
			fmt.Fprintf(w, "            %-120s : %d ", name, len(proj.Files))
			if forkCount != 0 {
				fmt.Fprintf(w, " (%d)\n", forkCount)
			} else {
				fmt.Fprintf(w, " \n")
			}

			if verbose {
				for _, file := range proj.Files {
					var fork string
					if file.BranchDiff != nil {
						fork = fmt.Sprintf("(%d+ %d-)", file.BranchDiff.AddedLines, file.BranchDiff.DeletedLines)
					}
					fmt.Fprintf(w, "               %-20s %s\n", fork, file.Filename)
				}

			}
		}

	}
	fmt.Fprintln(w, "  Targets")
	for _, t := range rsp.Report.Targets {
		targetPrint(t)
	}

	fmt.Fprintln(w, "  Run Times")
	for _, p := range rsp.Profile {
		fmt.Fprintf(w, "     %-30s : %f secs\n", p.Description, p.DurationSecs)
	}

}
