/******************************************************************************
 * Copyright (c)  2022 PingCAP                                                *
 * 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,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 ******************************************************************************/

/*******************************************************************************
 * @File: main_test.go
 * @Description:
 * @Author: jiangxunyu@pingcap.com
 * @Version: 1.0.0
 * @Date: 2022/6/30 18:20
*******************************************************************************/

package globalapi

import (
	"context"
	"net/http"
	"net/http/httptest"
	"os"
	"testing"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/credentials"
	"github.com/gin-gonic/gin"
	"github.com/tidbcloud/observability/pkg/common/awsauth"
	"github.com/tidbcloud/observability/pkg/common/constants"
	"github.com/tidbcloud/observability/pkg/common/metrics"
	"github.com/tidbcloud/observability/pkg/common/structs"
	"github.com/tidbcloud/observability/pkg/globalservice"
	metaservice "github.com/tidbcloud/observability/pkg/metamanager/etcd"
	testClient "k8s.io/client-go/kubernetes/fake"
	"k8s.io/client-go/rest/fake"
)

var testEngine *gin.Engine

var requestParameters = structs.RequestParameters{
	CommonReqInfo: structs.CommonReqInfo{
		Vendor: constants.AWS,
		Region: "us-west-2",
	},
	Headers: map[string]string{
		"vendor": "aws",
		"region": "us-west-2",
		"Auth":   "Bearer test_token",
	},
	QueryParams: map[string]string{
		"queryKey": "queryValue",
	},
	PathParams: []gin.Param{{
		Key:   "id",
		Value: "123456",
	}},
	FormParams: map[string]string{
		"formKey": "formValue",
	},
	BodyParams: "{\"bodyKey\": \"bodyValue\"}",
}

func TestMain(m *testing.M) {
	testEngine = gin.Default()
	metrics.SetupMetrics()
	route(testEngine)

	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusOK)
		w.Write([]byte(`
{
    "code": 0,
    "message": "",
    "data":{
		"id": "aaa",
		"monitorInfo":{
			"specID": "spec1"
		},
		"lastScaleTime": {
			"spec": "0",
            "storage": "0"
        },
		"clusterID": "12345",
        "serviceName":"observability_regional_server",
        "availableSpecs":{
            "spec1":{
                "requests":{
                    "cpu":"0.1",
                    "memory":"512Mi",
                    "storage":"5Gi"
                }
            },
            "spec2":{
                "requests":{
                    "cpu":"0.25",
                    "memory":"1Gi",
                    "storage":"10Gi"
                }
            },
			"t1g.small.micro":{
                "requests":{
                    "cpu":"0.25",
                    "memory":"1Gi",
                    "storage":"8Gi"
                }
            },
			"t1g.micro":{
                "requests":{
                    "cpu":"0.5",
                    "memory":"2Gi",
                    "storage":"16Gi"
                }
            },
			"t1g.small":{
                "requests":{
                    "cpu":"1",
                    "memory":"4Gi",
                    "storage":"32Gi"
                }
            },
			"t1g.medium":{
                "requests":{
                    "cpu":"2",
                    "memory":"8Gi",
                    "storage":"64Gi"
                }
            },
			"t1m.small.micro":{
                "requests":{
                    "cpu":"0.25",
                    "memory":"2Gi",
                    "storage":"8Gi"
                }
            },
			"t1m.micro":{
                "requests":{
                    "cpu":"0.5",
                    "memory":"4Gi",
                    "storage":"16Gi"
                }
            },
			"t1m.small":{
                "requests":{
                    "cpu":"1",
                    "memory":"8Gi",
                    "storage":"32Gi"
                }
            },
			"t1m.medium":{
                "requests":{
                    "cpu":"2",
                    "memory":"16Gi",
                    "storage":"64Gi"
                }
            }
        }
    }
}
`))
		r.ParseForm()
	}))
	defer server.Close()

	cli := testClient.NewSimpleClientset()
	err := metaservice.NewConfigMapMetaService(cli).CreateMeta(context.TODO(), constants.ObservabilityBaseServiceName, `
		{
            "maxSpec": "2C8G",
			"vendors": {
				"aws": [
					{
						"region": "us-west-2",
						"routers": [{
							"dnsAddress": "`+server.URL+`",
							"primary": true,
							"logicalRegionName": "us-west-2-primary"
						},{
							"dnsAddress": "`+server.URL+`",
							"logicalRegionName": "us-west-2-secondary"
						}]
					}
				]
			},
			"routes": {
				"aws-us-west-2": {
					"tidbcloud:12345:.*": "us-west-2-primary",
					"tidbcloud:.*:.*": "us-west-2-secondary",
					"byoc:.*:.*": "us-west-2-primary"
				}
			},
			"auth0": {
				"issuerUrl": "https://test.us.auth0.com/",
				"audience": "https://test.us.auth0.com/api/v2/"
			},
			"server":{
		        "bizToAccountProviderSvcAddr": {
                    "tidbcloud": "`+server.URL+`",
                    "dev-tidbcloud": "`+server.URL+`",
                    "staging-tidbcloud": "`+server.URL+`",
										"byoc": "`+server.URL+`"
                }
			}
		}
		`)
	if err != nil {
		panic(err)
	}
	if err = globalservice.NewManager(context.TODO(), cli); err != nil {
		panic(err)
	}

	// mock aws config
	mockAwsConfig()

	code := m.Run()
	os.Exit(code)
}

// mock session which is used to hit the mock server
func mockAwsConfig() {
	cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion("us-west-2"),
		config.WithCredentialsProvider(credentials.StaticCredentialsProvider{Value: aws.Credentials{
			AccessKeyID:     "test_id",
			SecretAccessKey: "test_key",
			SessionToken:    "test_session_token",
		}}),
		config.WithHTTPClient(fake.CreateHTTPClient(func(request *http.Request) (*http.Response, error) {
			return &http.Response{StatusCode: 200}, nil
		})))
	if err != nil {
		panic(err)
	}
	awsauth.SetAwsConfig(&cfg)
}
