package bp2build

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

	"android/soong/android"
	"android/soong/shared"
	"android/soong/ui/metrics/bp2build_metrics_proto"
	"google.golang.org/protobuf/proto"

	"github.com/google/blueprint"
)

// CodegenMetrics represents information about the Blueprint-to-BUILD
// conversion process.
// Use CreateCodegenMetrics() to get a properly initialized instance
type CodegenMetrics struct {
	serialized *bp2build_metrics_proto.Bp2BuildMetrics
	// List of modules with unconverted deps
	// NOTE: NOT in the .proto
	moduleWithUnconvertedDepsMsgs []string

	// List of modules with missing deps
	// NOTE: NOT in the .proto
	moduleWithMissingDepsMsgs []string

	// Map of converted modules and paths to call
	// NOTE: NOT in the .proto
	convertedModulePathMap map[string]string
}

func CreateCodegenMetrics() CodegenMetrics {
	return CodegenMetrics{
		serialized: &bp2build_metrics_proto.Bp2BuildMetrics{
			RuleClassCount:           make(map[string]uint64),
			ConvertedModuleTypeCount: make(map[string]uint64),
			TotalModuleTypeCount:     make(map[string]uint64),
			UnconvertedModules:       make(map[string]*bp2build_metrics_proto.UnconvertedReason),
		},
		convertedModulePathMap: make(map[string]string),
	}
}

// Serialize returns the protoized version of CodegenMetrics: bp2build_metrics_proto.Bp2BuildMetrics
func (metrics *CodegenMetrics) Serialize() *bp2build_metrics_proto.Bp2BuildMetrics {
	return metrics.serialized
}

// Print the codegen metrics to stdout.
func (metrics *CodegenMetrics) Print() {
	generatedTargetCount := uint64(0)
	for _, ruleClass := range android.SortedKeys(metrics.serialized.RuleClassCount) {
		count := metrics.serialized.RuleClassCount[ruleClass]
		fmt.Printf("[bp2build] %s: %d targets\n", ruleClass, count)
		generatedTargetCount += count
	}
	fmt.Printf(
		`[bp2build] Converted %d Android.bp modules to %d total generated BUILD targets. Included %d handcrafted BUILD targets. There are %d total Android.bp modules.
%d converted modules have unconverted deps:
	%s
%d converted modules have missing deps:
	%s
`,
		metrics.serialized.GeneratedModuleCount,
		generatedTargetCount,
		metrics.serialized.HandCraftedModuleCount,
		metrics.TotalModuleCount(),
		len(metrics.moduleWithUnconvertedDepsMsgs),
		strings.Join(metrics.moduleWithUnconvertedDepsMsgs, "\n\t"),
		len(metrics.moduleWithMissingDepsMsgs),
		strings.Join(metrics.moduleWithMissingDepsMsgs, "\n\t"),
	)
}

const bp2buildMetricsFilename = "bp2build_metrics.pb"

// fail prints $PWD to stderr, followed by the given printf string and args (vals),
// then the given alert, and then exits with 1 for failure
func fail(err error, alertFmt string, vals ...interface{}) {
	cwd, wderr := os.Getwd()
	if wderr != nil {
		cwd = "FAILED TO GET $PWD: " + wderr.Error()
	}
	fmt.Fprintf(os.Stderr, "\nIn "+cwd+":\n"+alertFmt+"\n"+err.Error()+"\n", vals...)
	os.Exit(1)
}

// Write the bp2build-protoized codegen metrics into the given directory
func (metrics *CodegenMetrics) Write(dir string) {
	if _, err := os.Stat(dir); os.IsNotExist(err) {
		// The metrics dir doesn't already exist, so create it (and parents)
		if err := os.MkdirAll(dir, 0755); err != nil { // rx for all; w for user
			fail(err, "Failed to `mkdir -p` %s", dir)
		}
	} else if err != nil {
		fail(err, "Failed to `stat` %s", dir)
	}
	metricsFile := filepath.Join(dir, bp2buildMetricsFilename)
	if err := metrics.dump(metricsFile); err != nil {
		fail(err, "Error outputting %s", metricsFile)
	}
	if _, err := os.Stat(metricsFile); err != nil {
		if os.IsNotExist(err) {
			fail(err, "MISSING BP2BUILD METRICS OUTPUT: %s", metricsFile)
		} else {
			fail(err, "FAILED TO `stat` BP2BUILD METRICS OUTPUT: %s", metricsFile)
		}
	}
}

// ReadCodegenMetrics loads CodegenMetrics from `dir`
// returns a nil pointer if the file doesn't exist
func ReadCodegenMetrics(dir string) *CodegenMetrics {
	metricsFile := filepath.Join(dir, bp2buildMetricsFilename)
	if _, err := os.Stat(metricsFile); err != nil {
		if os.IsNotExist(err) {
			return nil
		} else {
			fail(err, "FAILED TO `stat` BP2BUILD METRICS OUTPUT: %s", metricsFile)
			panic("unreachable after fail")
		}
	}
	if buf, err := os.ReadFile(metricsFile); err != nil {
		fail(err, "FAILED TO READ BP2BUILD METRICS OUTPUT: %s", metricsFile)
		panic("unreachable after fail")
	} else {
		bp2BuildMetrics := bp2build_metrics_proto.Bp2BuildMetrics{
			RuleClassCount:           make(map[string]uint64),
			ConvertedModuleTypeCount: make(map[string]uint64),
			TotalModuleTypeCount:     make(map[string]uint64),
		}
		if err := proto.Unmarshal(buf, &bp2BuildMetrics); err != nil {
			fail(err, "FAILED TO PARSE BP2BUILD METRICS OUTPUT: %s", metricsFile)
		}
		return &CodegenMetrics{
			serialized:             &bp2BuildMetrics,
			convertedModulePathMap: make(map[string]string),
		}
	}
}

func (metrics *CodegenMetrics) IncrementRuleClassCount(ruleClass string) {
	metrics.serialized.RuleClassCount[ruleClass] += 1
}

func (metrics *CodegenMetrics) AddEvent(event *bp2build_metrics_proto.Event) {
	metrics.serialized.Events = append(metrics.serialized.Events, event)
}

func (metrics *CodegenMetrics) SetSymlinkCount(n uint64) {
	if m := metrics.serialized.WorkspaceSymlinkCount; m != 0 {
		fmt.Fprintf(os.Stderr, "unexpected non-zero workspaceSymlinkCount of %d", m)
	}
	metrics.serialized.WorkspaceSymlinkCount = n
}

func (metrics *CodegenMetrics) SetMkDirCount(n uint64) {
	if m := metrics.serialized.WorkspaceMkDirCount; m != 0 {
		fmt.Fprintf(os.Stderr, "unexpected non-zero workspaceDirCount of %d", m)
	}
	metrics.serialized.WorkspaceMkDirCount = n
}

func (metrics *CodegenMetrics) TotalModuleCount() uint64 {
	return metrics.serialized.HandCraftedModuleCount +
		metrics.serialized.GeneratedModuleCount +
		metrics.serialized.UnconvertedModuleCount
}

// Dump serializes the metrics to the given filename
func (metrics *CodegenMetrics) dump(filename string) (err error) {
	ser := metrics.Serialize()
	return shared.Save(ser, filename)
}

type ConversionType int

const (
	Generated ConversionType = iota
	Handcrafted
)

func (metrics *CodegenMetrics) AddConvertedModule(m blueprint.Module, moduleType string, dir string) {
	//a package module has empty name
	if moduleType == "package" {
		return
	}
	// Undo prebuilt_ module name prefix modifications
	moduleName := android.RemoveOptionalPrebuiltPrefix(m.Name())
	metrics.serialized.ConvertedModules = append(metrics.serialized.ConvertedModules, moduleName)
	metrics.convertedModulePathMap[moduleName] = "//" + dir
	metrics.serialized.ConvertedModuleTypeCount[moduleType] += 1
	metrics.serialized.TotalModuleTypeCount[moduleType] += 1
	metrics.serialized.GeneratedModuleCount += 1
}

func (metrics *CodegenMetrics) AddUnconvertedModule(m blueprint.Module, moduleType string, dir string,
	reason android.UnconvertedReason) {
	//a package module has empty name
	if moduleType == "package" {
		return
	}
	// Undo prebuilt_ module name prefix modifications
	moduleName := android.RemoveOptionalPrebuiltPrefix(m.Name())
	metrics.serialized.UnconvertedModules[moduleName] = &bp2build_metrics_proto.UnconvertedReason{
		Type:   bp2build_metrics_proto.UnconvertedReasonType(reason.ReasonType),
		Detail: reason.Detail,
	}
	metrics.serialized.UnconvertedModuleCount += 1
	metrics.serialized.TotalModuleTypeCount[moduleType] += 1

	if reason.ReasonType == int(bp2build_metrics_proto.UnconvertedReasonType_DEFINED_IN_BUILD_FILE) {
		metrics.serialized.HandCraftedModuleCount += 1
	}
}
