package process

import (
	"context"
	"database/sql"

	_ "github.com/mattn/go-sqlite3"
	"github.com/tidbcloud/observability/cmd/diagnosis-compute/pkg/metrics"
	"github.com/tidbcloud/observability/cmd/diagnosis-compute/pkg/types"
)

func InitDB(ctx context.Context, dbPath string) (*sql.DB, error) {
	db, err := sql.Open("sqlite3", dbPath)
	if err != nil {
		return nil, err
	}
	_, err = db.ExecContext(ctx, `
			CREATE TABLE IF NOT EXISTS "log_stats" (
				"component" TEXT,
				"level" TEXT,
				"position" TEXT,
				"msg_digest" TEXT,
				"count" INTEGER,
				"sample" TEXT,
				"sample_object_key" TEXT
			);
		`)
	if err != nil {
		return nil, err
	}
	_, err = db.ExecContext(ctx, `
			CREATE TABLE IF NOT EXISTS "telemetry_stats" (
				"ts" INTEGER,
				"cluster_id" TEXT,
				"instance" TEXT,
				"telemetry_data" TEXT
			);
		`)
	if err != nil {
		return nil, err
	}
	return db, nil
}

func insertTelemetryData(ctx context.Context, db *sql.DB, logItem *types.Log, clusterID string) error {
	_, err := db.ExecContext(ctx, `
			INSERT INTO "telemetry_stats" (
				"ts",
				"cluster_id",
				"instance",
				"telemetry_data"
			) VALUES (
				?, ?, ?, ?
			);
		`, logItem.Timestamp, clusterID, logItem.Instance, logItem.TelemetryStr)
	if err != nil {
		return err
	}
	return nil
}

func saveStats(ctx context.Context, db *sql.DB, s *types.Stats, component string, info types.ClusterInfo) error {
	metrics.UniqueLogPatterns.WithLabelValues(info.StorageID, component).Set(float64(len(s.Count)))
	for k, item := range s.Data {
		count := s.Count[k]
		objectKey := s.SampleObjectKey[k]
		_, err := db.ExecContext(ctx, `
            INSERT INTO "log_stats" (
                "component",
                "level",
                "position",
                "msg_digest",
                "count",
                "sample",
                "sample_object_key"
            ) VALUES (
                ?, ?, ?, ?, ?, ?, ?
            );
        `, component, item.Level, item.Position, item.MsgDigest, count, item.RawLine, objectKey)
		if err != nil {
			return err
		}
	}
	return nil
}
