package plugin

import (
	"encoding/json"
	"reflect"
	"testing"
)

func TestConvertFields(t *testing.T) {
	input := []byte(
		`{
  "route": {
    "ws_id": "0dc6f45b-8f8d-40d2-a504-473544ee190b",
    "path_handling": "v0",
    "updated_at": 1746001063,
    "service": {
      "id": "00e4ee58-1159-57e1-93af-3911493c81f9"
    },
    "strip_path": false,
    "preserve_host": true,
    "created_at": 1746001063,
    "name": "tidb-admin.proxy-cluster-proxy.proxy-cluster-proxy..80",
    "id": "269d968b-8aec-5e14-b5c5-d80858ddced7",
    "methods": [
      "GET",
      "POST",
      "PUT",
      "DELETE",
      "PATCH",
      "OPTIONS",
      "HEAD",
      "TRACE"
    ],
    "paths": [
      "/proxy/",
      "~/proxy$"
    ],
    "tags": [
      "k8s-name:proxy-cluster-proxy",
      "k8s-namespace:tidb-admin",
      "k8s-kind:Ingress",
      "k8s-uid:25e24f92-5e65-4c4d-8b2f-8ab254d423e1",
      "k8s-group:networking.k8s.io",
      "k8s-version:v1"
    ],
    "regex_priority": 0,
    "request_buffering": true,
    "response_buffering": true,
    "https_redirect_status_code": 426,
    "protocols": [
      "http"
    ]
  },
  "request": {
    "headers": {
      "connection": "close",
      "authorization": "REDACTED",
      "accept-encoding": "gzip",
      "host": "k8s-tidbadmi-clusterg-f44ec6abe8-8e3327f18e1768a0.elb.us-west-2.amazonaws.com",
      "user-agent": "go-resty/2.13.1 (https://github.com/go-resty/resty)",
      "content-type": "text/plain; charset=utf-8",
      "b3": "202504300901333d2aa7220bd4e1f91c-80cbad808ba0aae8-1",
      "content-length": "187"
    },
    "size": 1301,
    "method": "POST",
    "id": "4c22e11169300476e6bf477d06be146e",
    "url": "http://k8s-tidbadmi-clusterg-f44ec6abe8-8e3327f18e1768a0.elb.us-west-2.amazonaws.com:80/proxy/cluster/10296538211933555660/change_password",
    "uri": "/proxy/cluster/10296538211933555660/change_password",
    "querystring": {
      "param1": "value1",
      "param2": "value2"
    }
  },
  "source": "upstream",
  "service": {
    "ws_id": "0dc6f45b-8f8d-40d2-a504-473544ee190b",
    "tags": [
      "k8s-name:proxy-cluster-proxy",
      "k8s-namespace:tidb-admin",
      "k8s-kind:Service",
      "k8s-uid:2f4e4f9b-5ff2-454d-b5cb-6f1b1e422a82",
      "k8s-version:v1"
    ],
    "connect_timeout": 60000,
    "read_timeout": 60000,
    "host": "proxy-cluster-proxy.tidb-admin.80.svc",
    "path": "/",
    "enabled": true,
    "name": "tidb-admin.proxy-cluster-proxy.80",
    "write_timeout": 60000,
    "retries": 5,
    "created_at": 1746001063,
    "updated_at": 1746001063,
    "port": 80,
    "id": "00e4ee58-1159-57e1-93af-3911493c81f9",
    "protocol": "http"
  },
  "upstream_uri": "/proxy/cluster/10296538211933555660/change_password",
  "tries": [
    {
      "ip": "172.16.0.83",
      "balancer_latency": 0,
      "port": 80,
      "balancer_start": 1746003694335,
      "balancer_start_ns": 1746003694335200000,
      "balancer_latency_ns": 20224
    }
  ],
  "response": {
    "headers": {
      "via": "kong/3.6.1",
      "x-kong-proxy-latency": "1",
      "x-kong-request-id": "4c22e11169300476e6bf477d06be146e",
      "x-kong-upstream-latency": "89",
      "connection": "close",
      "date": "Wed, 30 Apr 2025 09:01:34 GMT",
      "content-length": "0"
    },
    "status": 200,
    "size": 218
  },
  "upstream_status": "200",
  "client_ip": "54.71.2.116",
  "started_at": 1746003694334,
  "latencies": {
    "request": 91,
    "kong": 1,
    "proxy": 89
  }
}`)

	expected := Message{
		Timestamp:      1746003694334,
		ClientIP:       "54.71.2.116",
		RequestURI:     "/proxy/cluster/10296538211933555660/change_password",
		RequestMethod:  "POST",
		RequestParams:  map[string]string{"param1": "value1", "param2": "value2"},
		RequestBody:    "", // this field is empty now
		RequestSize:    1301,
		ResponseStatus: 200,
		ResponseSize:   218,
		Service:        "proxy-cluster-proxy.tidb-admin.80.svc",
		Latencies:      Latencies{Request: 91, Kong: 1, Proxy: 89},
	}

	output, err := convertFields(input)
	if err != nil {
		t.Fatalf("convertFields() error = %v", err)
	}

	var result Message
	if err := json.Unmarshal(output, &result); err != nil {
		t.Fatalf("json.Unmarshal() error = %v", err)
	}

	if !reflect.DeepEqual(result, expected) {
		t.Errorf("convertFields() = %v, want %v", result, expected)
	}
}

func TestConvertFields_NegativeLatency(t *testing.T) {
	input := []byte(
		`{
  "upstream_uri": "/api/v1/clusters/db-1960514102782590976/topology",
  "response": {
    "status": 401,
    "headers": {
      "content-length": "144",
      "server": "kong/3.6.1",
      "x-kong-request-id": "6db6ee2a4375f343600405052c84a205",
      "content-type": "text/html; charset=UTF-8",
      "connection": "close",
      "x-kong-response-latency": "20"
    },
    "size": 397
  },
  "client_ip": "10.0.113.206",
  "started_at": 1756376221163,
  "source": "kong",
  "service": {
    "read_timeout": 60000,
    "host": "cluster-agent.tidb1749334240185180.8080.svc",
    "enabled": true,
    "retries": 5,
    "name": "tidb1749334240185180.cluster-agent.8080",
    "created_at": 1756374601,
    "updated_at": 1756374601,
    "protocol": "http",
    "path": "/",
    "write_timeout": 60000,
    "id": "59ec976f-6d03-5562-b23c-d2605bafa9ca",
    "port": 8080,
    "ws_id": "0dc6f45b-8f8d-40d2-a504-473544ee190b",
    "connect_timeout": 60000,
    "tags": [
      "k8s-name:cluster-agent",
      "k8s-namespace:tidb1749334240185180",
      "k8s-kind:Service",
      "k8s-uid:af4657cb-dab4-48a5-aac7-a749f52e32d5",
      "k8s-version:v1"
    ]
  },
  "upstream_status": "",
  "route": {
    "preserve_host": true,
    "regex_priority": 0,
    "path_handling": "v0",
    "name": "tidb1749334240185180.cluster-agent.cluster-agent..8080",
    "created_at": 1756374601,
    "updated_at": 1756374601,
    "ws_id": "0dc6f45b-8f8d-40d2-a504-473544ee190b",
    "https_redirect_status_code": 426,
    "service": {
      "id": "59ec976f-6d03-5562-b23c-d2605bafa9ca"
    },
    "request_buffering": true,
    "strip_path": true,
    "response_buffering": true,
    "id": "08cecb79-2b4c-52d6-a82c-d9b8ed57e998",
    "protocols": [
      "http"
    ],
    "paths": [
      "/cluster-agent/tidb1749334240185180/",
      "~/cluster-agent/tidb1749334240185180$"
    ],
    "tags": [
      "k8s-name:cluster-agent",
      "k8s-namespace:tidb1749334240185180",
      "k8s-kind:Ingress",
      "k8s-uid:3ca1f70c-7353-46ed-98f4-6620059b5bd8",
      "k8s-group:networking.k8s.io",
      "k8s-version:v1"
    ],
    "methods": [
      "GET",
      "POST",
      "PUT",
      "DELETE",
      "PATCH",
      "OPTIONS",
      "HEAD",
      "TRACE"
    ]
  },
  "latencies": {
    "proxy": -1,
    "kong": 20,
    "request": 20
  },
  "request": {
    "id": "6db6ee2a4375f343600405052c84a205",
    "url": "https://vpce-0ae9f75ba73d011f5-hn972j4r.vpce-svc-03138ae661ba7efdb.us-west-2.vpce.amazonaws.com:443/cluster-agent/tidb1749334240185180/api/v1/clusters/db-1960514102782590976/topology",
    "tls": {
      "version": "TLSv1.3",
      "cipher": "TLS_AES_256_GCM_SHA384",
      "client_verify": "NONE"
    },
    "size": 1867,
    "headers": {
      "authorization": "REDACTED",
      "accept": "*/*",
      "user-agent": "curl/8.14.1",
      "host": "vpce-0ae9f75ba73d011f5-hn972j4r.vpce-svc-03138ae661ba7efdb.us-west-2.vpce.amazonaws.com"
    },
    "uri": "/cluster-agent/tidb1749334240185180/api/v1/clusters/db-1960514102782590976/topology",
    "method": "POST",
    "querystring": {}
  },
  "tries": []
}    `)

	expected := Message{
		Timestamp:      1756376221163,
		ClientIP:       "10.0.113.206",
		RequestURI:     "/cluster-agent/tidb1749334240185180/api/v1/clusters/db-1960514102782590976/topology",
		RequestMethod:  "POST",
		RequestParams:  map[string]string{},
		RequestBody:    "",
		RequestSize:    1867,
		ResponseSize:   397,
		ResponseStatus: 401,
		Service:        "cluster-agent.tidb1749334240185180.8080.svc",
		Latencies:      Latencies{Proxy: -1, Kong: 20, Request: 20},
	}
	output, err := convertFields(input)
	if err != nil {
		t.Fatalf("failed to convert fields: %v", err)
	}

	var result Message
	if err := json.Unmarshal(output, &result); err != nil {
		t.Fatalf("json.Unmarshal() error = %v", err)
	}

	if !reflect.DeepEqual(result, expected) {
		t.Errorf("convertFields() = %v, want %v", result, expected)
	}
}
