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),
		},
		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) AddUnconvertedModule(moduleType string) {
	metrics.serialized.UnconvertedModuleCount += 1
	metrics.serialized.TotalModuleTypeCount[moduleType] += 1
}

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, conversionType ConversionType) {
	//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

	if conversionType == Handcrafted {
		metrics.serialized.HandCraftedModuleCount += 1
	} else if conversionType == Generated {
		metrics.serialized.GeneratedModuleCount += 1
	}
}
