/*
 * Copyright 2021 PingCAP, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package main

import (
	"context"
	"fmt"
	"github.com/jinzhu/now"
	"os"
	"testing"
	"time"
)

func TestTimeParse(t *testing.T) {
	s1 := `2021-06-03T10:21:13Z`
	s2 := `2021-06-03T04:21:13-07:00`
	s3 := `2021-06-03T03:21:13-07:00`
	ts1, err := time.Parse(time.RFC3339, s1)
	if err != nil {
		t.Fatal(err)
	}
	t.Log(ts1.Unix())
	t.Log(ts1.Format(time.RFC3339))
	ts2, err := time.Parse(time.RFC3339, s2)
	if err != nil {
		t.Fatal(err)
	}
	t.Log(ts2.Unix())
	t.Log(ts2.Format(time.RFC3339))

	ts3, err := time.Parse(time.RFC3339, s3)
	if err != nil {
		t.Fatal(err)
	}
	t.Log(ts3.Unix())
	t.Log(ts3.Format(time.RFC3339))


	t.Log(ts2.Unix() - ts1.Unix())
	t.Log(ts3.Unix() - ts1.Unix())
}

func TestTimeFormat(t *testing.T) {
	n := time.Now()
	t.Log(n.Format("2006-01-02 15:04:05 -07:00"))
}

func TestCollectorCollect(t *testing.T) {
	dup := make(map[string]struct{})
	cnt := 0
	other := 0

	endTime := now.With(time.Now().Local()).BeginningOfDay()
	startTime := endTime.AddDate(0,0,-1)
	t.Log(startTime.Format(time.RFC3339))
	t.Log(endTime.Format(time.RFC3339))
	ak := os.Getenv("PAGERDUTY_AK")
	c := New(ak, startTime, endTime)
	sink := c.GetSink()
	go func (){if err := c.collect(context.Background()); err != nil {
		t.Error(err)
	}}()
	for {
		select {
			case a, ok := <- sink:
				if !ok {
					t.Logf("cnt: %+v", cnt)
					t.Logf("dup: %+v", len(dup))
					t.Logf("other: %+v", other)
					return
				}
				if _, ok := dup[a.AlertID]; !ok {
					t.Logf("%+v\n",a)
					other++
				}
				cnt++

		}
	}
}

func TestCollectorDrain(t *testing.T) {
	dup := make(map[string]struct{})
	cnt := 0

	endTime := now.With(time.Now().Local()).BeginningOfDay()
	startTime := endTime.AddDate(0,0,-1)
	t.Log(now.With(time.Now().Local()).BeginningOfYear().Format(time.RFC3339))
	t.Log(now.With(time.Now().Local()).Format(time.RFC3339))
	ak := os.Getenv("PAGERDUTY_AK")
	c := New(ak, startTime, endTime)
	c.SetDrainRange("2020-01-01T00:00:00Z", "2020-03-01T23:59:59Z")
	sink := c.GetSink()
	go func (){if err := c.drain(context.Background()); err != nil {
		t.Error(err)
	}}()
	for {
		select {
		case a, ok := <- sink:
			if !ok {
				t.Logf("cnt: %+v", cnt)
				t.Logf("dup: %+v", len(dup))
				return
			}
			t.Logf("%+v\n",a)

			//if _, ok := dup[a.AlertID]; !ok {
			//	t.Logf("%+v\n",a)
			//}
			cnt++
		}
	}
}

func TestParseLabel(t *testing.T) {
	tt := []struct{
		input string
		expect string
	}{
		{
			input: `Labels:
- alertname = KubePodCrashLoopingInControlPlane
`,
			expect: ",,KubePodCrashLoopingInControlPlane",
		},
		{
			input: `Labels:
- alertname = KubePodCrashLoopingInControlPlane
- tenant = 123
`,
			expect: "123,,KubePodCrashLoopingInControlPlane",
		},
		{
			input: `Labels:
- alertname = KubePodCrashLoopingInControlPlane
- tenant_id = 123
`,
			expect: "123,,KubePodCrashLoopingInControlPlane",
		},
		{
			input: `Labels:
- alertname = KubePodCrashLoopingInControlPlane
- tenant_id = 123
- cluster_id = 456
`,
			expect: "123,456,KubePodCrashLoopingInControlPlane",
		},
		{
			input: `Labels:
- alertname = KubePodCrashLoopingInControlPlane
- tenant_id = 123
- kubernetes_namespace = tidb456
`,
			expect: "123,456,KubePodCrashLoopingInControlPlane",
		},
		{
			// msg contain `：`
			input: `Labels:
 - msg = dial tcp: lookup db-tidb on 100.64.0.10:53: no such host
 - alertname = KubePodCrashLoopingInControlPlane
 - tenant_id = 123
 - kubernetes_namespace = tidb456
`,
			expect: "123,456,KubePodCrashLoopingInControlPlane",
		},
		{
			// msg contain `\n\t`
			input: `Labels:
 - alertname = ImportFail
 - cluster_id = 456
 - msg = AccessDenied: Access Denied
	status code: 403, request id: 6ZHS760K758EYJD2, host id: fyO0KBtBV+aGk9VIsIQJSljKBBdr1R3LNpEA+K9uxF0Y40YvVjhFCOZaFDNxoqniaEnGXuEZG1k=
 - tenant = 123`,
 		expect: "123,456,ImportFail",
		},
	}

	for _, tc := range tt {
		t.Run("", func(t *testing.T) {
			tenantID, clusterID, alertName, err := parseLabel(tc.input)
			if err != nil {
				t.Error(err)
			}
			if fmt.Sprintf("%v,%v,%v", tenantID, clusterID, alertName) != tc.expect {
				t.Error("not match")
			}
		})
	}
}

func TestCornerCase(t *testing.T) {
	input := "Labels:\n - alertname = ImportFail\n - alerttype = event\n - cluster = base/eks/us-west-2\n - cluster_id = 1379661944580074068\n - endpoint = metrics\n - import_id = 120024\n - instance = 10.0.189.172:9090\n - job = central-metrics\n - msg = AccessDenied: Access Denied\n\tstatus code: 403, request id: 6ZHS760K758EYJD2, host id: fyO0KBtBV+aGk9VIsIQJSljKBBdr1R3LNpEA+K9uxF0Y40YvVjhFCOZaFDNxoqniaEnGXuEZG1k=\n - namespace = prod\n - pod = central-mipbivsb-b8cbf89bf-khfc4\n - prometheus = monitoring/k8s\n - provider = eks\n - region = us-west-2\n - service = central-metrics\n - severity = warning\n - tenant = 1372813089187761282\nAnnotations:\n - message = import 120024 for cluster 1379661944580074068 failed cause AccessDenied: Access Denied\n\tstatus code: 403, request id: 6ZHS760K758EYJD2, host id: fyO0KBtBV+aGk9VIsIQJSljKBBdr1R3LNpEA+K9uxF0Y40YvVjhFCOZaFDNxoqniaEnGXuEZG1k=.\nSource: http://prometheus-k8s-0:9090/graph?g0.expr=dbaas_import_fail%7Bmsg%21~%22.%2Aplease+clean+up+the+table+first.%2A%7C.%2Ano+schema+create+sql+files+found.%2A%7C.%2AAccess+denied+for+user.%2A%22%7D&g0.tab=1\n"
	tid, cid, name, err := parseLabel(input)
	if err != nil {
		t.Fatal(err)
	}
	if fmt.Sprintf("%v,%v,%v", tid, cid, name) != "1372813089187761282,1379661944580074068,ImportFail" {
		t.Fatal("not match")
	}
}
