package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/tidbcloud/observability/test/webconsolee2e/cases"
	"github.com/tidbcloud/observability/test/webconsolee2e/framework"
)

func main() {
	clusterID := flag.String("cluster-id", "", "Target cluster ID (required)")
	authToken := flag.String("auth-token", "", "Authentication token (required)")
	clusterType := flag.String("cluster-type", "dedicated", "Cluster type: dedicated, shared, nextgen (default: dedicated)")
	enableNewPath := flag.Bool("newpath", false, "Enable new API path testing for dedicated clusters")
	orgID := flag.String("org-id", "", "Organization ID / Tenant ID (required)")
	projectID := flag.String("project-id", "", "Project ID (required)")
	regionID := flag.String("region-id", "", "Region ID for x-region-id header (required)")
	origin := flag.String("origin", "https://tidbcloud.com", "Request origin header")
	bizType := flag.String("biz-type", "tidbcloud", "Business type in URL path")
	o11yGSURL := flag.String("o11y-gs-url", "", "Observability global server URL")
	o11yGatewayURL := flag.String("o11y-gateway-url", "", "Observability gateway URL (for new path testing)")
	clinicURL := flag.String("clinic-url", "", "Clinic server URL (for keyvisual, etc.)")
	configFile := flag.String("config", "", "Configuration file path (optional)")
	outputFile := flag.String("output", "", "Output report file path (optional)")
	retryCount := flag.Int("retry", 0, "Retry count for failed cases")
	verbose := flag.Bool("verbose", false, "Enable verbose output")

	flag.Parse()

	// load configuration
	config := framework.LoadConfigOrDefault(*configFile)

	// override config with command-line arguments
	if *o11yGSURL != "" {
		config.O11yGSURL = *o11yGSURL
	}
	if *o11yGatewayURL != "" {
		config.O11yGatewayURL = *o11yGatewayURL
	}
	if *clinicURL != "" {
		config.ClinicURL = *clinicURL
	}
	if *orgID != "" {
		config.OrgID = *orgID
	}
	if *projectID != "" {
		config.ProjectID = *projectID
	}
	if *regionID != "" {
		config.RegionID = *regionID
	}
	if *origin != "https://tidbcloud.com" && *origin != "" {
		config.Origin = *origin
	}
	if *bizType != "tidbcloud" && *bizType != "" {
		config.BizType = *bizType
	}
	if *outputFile != "" {
		config.OutputFile = *outputFile
	}
	if *retryCount > 0 {
		config.RetryCount = *retryCount
	}
	if *enableNewPath {
		config.EnableNewPath = true
	}
	config.Verbose = *verbose

	if *clusterID == "" {
		fmt.Fprintln(os.Stderr, "Error: --cluster-id is required")
		flag.Usage()
		os.Exit(1)
	}
	if *authToken == "" {
		fmt.Fprintln(os.Stderr, "Error: --auth-token is required")
		flag.Usage()
		os.Exit(1)
	}
	if config.OrgID == "" {
		fmt.Fprintln(os.Stderr, "Error: --org-id is required (or set orgID in config file)")
		flag.Usage()
		os.Exit(1)
	}
	// projectID is only required for dedicated clusters (not for nextgen/shared)
	if config.ProjectID == "" && *clusterType == "dedicated" {
		fmt.Fprintln(os.Stderr, "Error: --project-id is required for dedicated clusters (or set projectID in config file)")
		flag.Usage()
		os.Exit(1)
	}
	if config.RegionID == "" {
		fmt.Fprintln(os.Stderr, "Error: --region-id is required (or set regionID in config file)")
		flag.Usage()
		os.Exit(1)
	}

	if !cases.IsValidClusterType(*clusterType) {
		fmt.Fprintf(os.Stderr, "Error: invalid cluster type '%s', valid types are: %v\n", *clusterType, cases.ValidClusterTypes())
		flag.Usage()
		os.Exit(1)
	}

	if err := config.Validate(); err != nil {
		fmt.Fprintf(os.Stderr, "Configuration error: %v\n", err)
		os.Exit(1)
	}

	fw := framework.NewTestFramework(*clusterID, *authToken, config)

	if err := cases.RegisterCases(fw, cases.ClusterType(*clusterType)); err != nil {
		fmt.Fprintf(os.Stderr, "Failed to register test cases: %v\n", err)
		os.Exit(1)
	}

	report := fw.Run()

	jsonReport, err := report.ToJSON()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to generate JSON report: %v\n", err)
		os.Exit(1)
	}

	if config.OutputFile != "" {
		if err := report.SaveToFile(config.OutputFile); err != nil {
			fmt.Fprintf(os.Stderr, "Failed to save report to file: %v\n", err)
			os.Exit(1)
		}
		fmt.Printf("\n📄 Report saved to: %s\n", config.OutputFile)
	} else {

		fmt.Println("\n📄 JSON Report:")
		fmt.Println(jsonReport)
	}

	if !report.IsAllPassed() {
		os.Exit(1)
	}
}
