// 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 engine

import (
	"fmt"
	"github.com/jarcoal/httpmock"
	"net/http"
	"testing"
	"time"

	"github.com/pingcap-inc/rule-engine/log/config"
	"github.com/stretchr/testify/require"
)

func TestKibanaLink(t *testing.T) {
	assert := require.New(t)

	eg, err := New(&EngineConfig{
		ClusterID:      "1e6f6b90-475a-11ec-bd35-a5f58f7843c2",
		KibanaIndex:    "1e6f6b90-475a-11ec-bd35-a5f58f7843c2",
		ESEndpoint:     "http://mock.es.com",
		KibanaEndpoint: "http://kibana-209e950d6bc28fd0.elb.cn-north-1.amazonaws.com.cn:5601",
		BeginTime:      time.Date(2021, 11, 17, 0, 0, 0, 0, time.UTC),
		EndTime:        time.Date(2021, 11, 18, 0, 0, 0, 0, time.UTC),
	})
	assert.Nil(err)
	link := eg.buildKibanaLink(&config.RuleItem{
		Patterns: config.LogPattern{
			Component: "tiflash",
			Message:   []string{"IOLimitTuner", "NOT need to tune"},
		},
	})
	assert.Equal(`http://kibana-209e950d6bc28fd0.elb.cn-north-1.amazonaws.com.cn:5601/app/discover#/?_a=(index:'1e6f6b90-475a-11ec-bd35-a5f58f7843c2',query:(language:kuery,query:'component:tiflash and message:"IOLimitTuner" and message:"NOT need to tune"'))&_g=(time:(from:'2021-11-17T00%3A00%3A00Z',to:'2021-11-18T00%3A00%3A00Z'))`, link)
}

func TestBuildQuery(t *testing.T) {
	assert := require.New(t)

	eg, err := New(&EngineConfig{
		ClusterID:      "6924974196193154048",
		KibanaIndex:    "1e6f6b90-475a-11ec-bd35-a5f58f7843c2",
		ESEndpoint:     "http://mock.es.com",
		KibanaEndpoint: "http://kibana-209e950d6bc28fd0.elb.cn-north-1.amazonaws.com.cn:5601",
		BeginTime:      time.Date(2021, 12, 03, 0, 0, 0, 0, time.UTC),
		EndTime:        time.Date(2021, 12, 14, 0, 0, 0, 0, time.UTC),
	})
	assert.Nil(err)

	q, err := eg.buildQuery(&config.RuleItem{
		Patterns: config.LogPattern{
			Component: "tidb",
			Message:   []string{"command dispatched failed"},
		},
	})
	assert.Nil(err)

	assert.Equal(`{"query":{"bool":{"filter":[{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"component":"tidb"}}]}},{"bool":{"should":[{"match_phrase":{"message":"command dispatched failed"}}]}}]}},{"range":{"timestamp":{"gte":"2021-12-03T00:00:00Z","lte":"2021-12-14T00:00:00Z"}}}]}},"size":0}`, q)
}

func TestBasicAuth(t *testing.T) {
	assert := require.New(t)
	httpmock.Activate()
	defer httpmock.DeactivateAndReset()

	mockESEndpoint := "http://mock.com:9200"

	httpmock.RegisterResponder(http.MethodPost, fmt.Sprintf("%s/clinic/_search", mockESEndpoint),
		func(req *http.Request) (*http.Response, error) {
			if username, password, ok := req.BasicAuth(); !ok {
				return httpmock.NewJsonResponse(http.StatusUnauthorized, struct{}{})
			} else if username != "root" || password != "root" {
				return httpmock.NewJsonResponse(http.StatusUnauthorized, struct{}{})
			}
			resp, err := httpmock.NewJsonResponse(200, struct{}{})
			if err != nil {
				return httpmock.NewStringResponse(500, ""), nil
			}
			return resp, nil
		},
	)
	httpmock.RegisterResponder(http.MethodGet, "/", func(request *http.Request) (*http.Response, error) {
		resp, _ := httpmock.NewJsonResponse(http.StatusOK, struct{}{})
		return resp, nil
	})
	cfg := EngineConfig{
		ClusterID:  "clinic",
		ESEndpoint: mockESEndpoint,
		BeginTime:  time.Now(),
		EndTime:    time.Now(),
	}
	eng, err := New(&cfg, WithBasicAuth("root", "root"))
	assert.Nil(err)
	_, err = eng.isQueryHit("")
	assert.Nil(err)
}
