package dialect

import (
	"testing"
)

func TestCastTypeReplace_BigQuery(t *testing.T) {
	tests := []struct {
		name   string
		input  string
		engine string
		want   string
	}{
		{
			name:   "CAST AS SIGNED -> INT64",
			input:  "SELECT CAST(x AS SIGNED) FROM t WHERE date = '20260410'",
			engine: "bigquery",
			want:   "select cast(`x` as INT64) from `t` where `date`='20260410'",
		},
		{
			name:   "CAST AS UNSIGNED -> INT64",
			input:  "SELECT CAST(x AS UNSIGNED) FROM t WHERE date = '20260410'",
			engine: "bigquery",
			want:   "select cast(`x` as INT64) from `t` where `date`='20260410'",
		},
		{
			name:   "nested CAST in REGEXP_EXTRACT 2-arg",
			input:  "SELECT CAST(REGEXP_EXTRACT(col, 'pattern([0-9]+)') AS SIGNED) FROM t WHERE date = '20260410'",
			engine: "bigquery",
			want:   "select cast(regexp_extract(`col`, 'pattern([0-9]+)') as INT64) from `t` where `date`='20260410'",
		},
		{
			name:   "nested CAST in REGEXP_EXTRACT 3-arg",
			input:  "SELECT CAST(REGEXP_EXTRACT(col, 'pattern([0-9]+)', 1) AS SIGNED) FROM t WHERE date = '20260410'",
			engine: "bigquery",
			want:   "select cast(regexp_extract(`col`, 'pattern([0-9]+)', 1) as INT64) from `t` where `date`='20260410'",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, err := RewriteForEngine(tt.input, tt.engine, nil)
			if err != nil {
				t.Fatalf("RewriteForEngine() error = %v", err)
			}
			if got != tt.want {
				t.Errorf("RewriteForEngine()\n  got  = %q\n  want = %q", got, tt.want)
			}
		})
	}
}

func TestCastTypeReplace_Athena(t *testing.T) {
	tests := []struct {
		name   string
		input  string
		engine string
		want   string
	}{
		{
			name:   "CAST AS SIGNED -> BIGINT",
			input:  "SELECT CAST(x AS SIGNED) FROM t WHERE date = '20260410'",
			engine: "athena",
			want:   `select cast("x" as BIGINT) from "t" where "date"='20260410'`,
		},
		{
			name:   "CAST AS UNSIGNED -> BIGINT",
			input:  "SELECT CAST(x AS UNSIGNED) FROM t WHERE date = '20260410'",
			engine: "athena",
			want:   `select cast("x" as BIGINT) from "t" where "date"='20260410'`,
		},
		{
			name:   "nested CAST in REGEXP_EXTRACT 3-arg",
			input:  "SELECT CAST(REGEXP_EXTRACT(col, 'TableFullScan[^}]+actRows[^0-9]+([0-9]+)', 1) AS SIGNED) FROM t WHERE date = '20260410'",
			engine: "athena",
			want:   `select cast(regexp_extract("col", 'TableFullScan[^}]+actRows[^0-9]+([0-9]+)', 1) as BIGINT) from "t" where "date"='20260410'`,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, err := RewriteForEngine(tt.input, tt.engine, nil)
			if err != nil {
				t.Fatalf("RewriteForEngine() error = %v", err)
			}
			if got != tt.want {
				t.Errorf("RewriteForEngine()\n  got  = %q\n  want = %q", got, tt.want)
			}
		})
	}
}

func TestRewriteForEngine_MaxComputeSlowlogAggregates(t *testing.T) {
	queries := map[string]string{
		"stats": "SELECT COUNT(*) AS total_count, " +
			"percentile_approx(CAST(query_time AS DOUBLE), 0.5) AS p50, " +
			"percentile_approx(CAST(query_time AS DOUBLE), 0.9) AS p90, " +
			"percentile_approx(CAST(query_time AS DOUBLE), 0.99) AS p99, " +
			"MAX(CAST(query_time AS DOUBLE)) AS max_val " +
			"FROM clinic_data_proxy.slow_query_logs " +
			"WHERE date IN ('20260824', '20260825') " +
			"AND time >= 1787587200.000000 AND time <= 1787673600.000000 " +
			"AND is_internal = false",
		"top digests": "SELECT digest, COUNT(*) AS cnt, " +
			"ROUND(AVG(CAST(query_time AS DOUBLE)) * 1000, 2) AS avg_ms, " +
			"ROUND(percentile_approx(CAST(query_time AS DOUBLE), 0.99) * 1000, 2) AS p99_ms, " +
			"ROUND(SUM(CAST(query_time AS DOUBLE)) * 1000, 2) AS total_ms, " +
			"any_value(query) AS sample_query " +
			"FROM clinic_data_proxy.slow_query_logs " +
			"WHERE date IN ('20260824', '20260825') " +
			"AND time >= 1787587200.000000 AND time <= 1787673600.000000 " +
			"AND is_internal = false " +
			"GROUP BY digest ORDER BY total_ms DESC LIMIT 5",
	}

	for name, sql := range queries {
		t.Run(name, func(t *testing.T) {
			if _, err := RewriteForEngine(sql, "maxcompute", &RewriteOptions{PartitionColumns: []string{"date"}}); err != nil {
				t.Fatalf("RewriteForEngine() rejected generated logical SQL: %v", err)
			}
		})
	}
}
