package main

import (
	"encoding/json"
	"fmt"
	"io"
	"os"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/pingcap/log"
	"go.uber.org/zap"
)

const (
	// S3 bucket for health check reports
	healthCheckReportBucket = "delicated-healthcheck"
	healthCheckReportPrefix = "healthcheck-report"
	awsProfile              = "clinic-dev"
	awsRegion               = "us-west-2"
)

func main() {
	// Report information from previous test
	clusterID := "1379661944646413035"
	reportID := "638fcdd1-ee5a-4acd-a440-257126ee4dc3"

	log.Info("Fetching health check report from S3",
		zap.String("cluster_id", clusterID),
		zap.String("report_id", reportID),
		zap.String("aws_profile", awsProfile),
		zap.String("aws_region", awsRegion),
	)

	// Build S3 key
	s3Key := fmt.Sprintf("%s/%s_%s_slow_query_hugeResourceUsage.json", healthCheckReportPrefix, clusterID, reportID)
	log.Info("S3 object key", zap.String("key", s3Key))

	// Initialize S3 client using shared config (AWS_PROFILE environment variable)
	// Set the profile via env var or use SharedConfigState
	_ = os.Setenv("AWS_PROFILE", awsProfile)

	sess, err := session.NewSessionWithOptions(session.Options{
		Profile:           awsProfile,
		SharedConfigState: session.SharedConfigEnable,
		Config: aws.Config{
			Region:                        aws.String(awsRegion),
			CredentialsChainVerboseErrors: aws.Bool(true),
		},
	})
	if err != nil {
		log.Fatal("Failed to create AWS session",
			zap.Error(err),
			zap.String("profile", awsProfile),
		)
	}

	// Get credentials info for debugging
	creds, err := sess.Config.Credentials.Get()
	if err != nil {
		log.Warn("Failed to get credentials (SSO login may be required)",
			zap.Error(err),
			zap.String("profile", awsProfile),
		)
		log.Info("Try running: aws sso login --profile clinic-dev")
	} else {
		log.Info("AWS credentials found",
			zap.String("access_key_id", creds.AccessKeyID),
			zap.String("provider_name", creds.ProviderName),
		)
	}

	s3Client := s3.New(sess)

	// Get object from S3
	resp, err := s3Client.GetObject(&s3.GetObjectInput{
		Bucket: aws.String(healthCheckReportBucket),
		Key:    aws.String(s3Key),
	})
	if err != nil {
		log.Fatal("Failed to get object from S3",
			zap.Error(err),
			zap.String("bucket", healthCheckReportBucket),
			zap.String("key", s3Key),
			zap.String("profile", awsProfile),
		)
	}
	defer resp.Body.Close()

	// Read body
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal("Failed to read S3 object body", zap.Error(err))
	}

	log.Info("Successfully fetched report from S3",
		zap.Int64("content_length", *resp.ContentLength),
		zap.String("content_type", *resp.ContentType),
	)

	// Try to parse as JSON and print formatted
	var reportContent any
	if err := json.Unmarshal(body, &reportContent); err != nil {
		log.Warn("Failed to parse report as JSON, printing raw content",
			zap.Error(err),
		)
		fmt.Println("\n========== RAW CONTENT ==========")
		fmt.Println(string(body))
		fmt.Println("=================================")
	} else {
		// Pretty print JSON
		prettyJSON, err := json.MarshalIndent(reportContent, "", "  ")
		if err != nil {
			log.Error("Failed to marshal report content", zap.Error(err))
			fmt.Println(string(body))
		} else {
			fmt.Println("\n========== REPORT CONTENT ==========")
			fmt.Println(string(prettyJSON))
			fmt.Println("====================================")
		}
	}

	// Save to local file
	filename := fmt.Sprintf("healthcheck_report_%s_%s.json", clusterID, reportID)
	if err := os.WriteFile(filename, body, 0o644); err != nil {
		log.Error("Failed to save report to file", zap.Error(err))
	} else {
		log.Info("Report saved to file", zap.String("filename", filename))
	}
}
