package test

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"testing"

	"github.com/pingcap/dbaas/billing2/utils/pp"
	"github.com/pingcap/dbaas/billing2/utils/timeutils"

	"github.com/aws/aws-sdk-go/aws/awsutil"

	"github.com/pingcap/dbaas/billing2/handler/cloudproviderhandler"
	"github.com/pingcap/dbaas/billing2/utils/log"
	"go.uber.org/zap"

	"github.com/aws/aws-sdk-go/service/pricing"
)

var (
	FilterType    = "TERM_MATCH"
	FilterTypePtr = &FilterType
)

func TestPrice2(t *testing.T) {
	t.Skip()

	providerPriceHandler := &cloudproviderhandler.AwsPriceHandlerImpl{}
	res, err := providerPriceHandler.GetPrice(map[string]string{
		"service_code": "EC2_Compute",
		"region":       "us-east-1",
		"instanceType": "c5.4xlarge",
	})
	if err != nil {
		log.Error("TestPrice2", zap.Error(err))
		return
	} else {
		log.Info("TestPrice2", zap.String("price ", res.Price.String()))
	}

}
func TestPriceS3(t *testing.T) {
	t.Skip()

	providerPriceHandler := &cloudproviderhandler.AwsPriceHandlerImpl{}
	res, err := providerPriceHandler.GetPrice(map[string]string{
		"service_code": "S3",
		"region":       "us-east-1",
	})
	if err != nil {
		log.Error("TestPriceS3", zap.Error(err))
		return
	} else {
		log.Info("TestPriceS3", zap.String("price ", res.Price.String()))
	}

}
func TestStoragePrice(t *testing.T) {
	t.Skip()
	//
	providerPriceHandler := &cloudproviderhandler.AwsPriceHandlerImpl{}
	//res, err := providerPriceHandler.GetPrice(map[string]string{
	//	"service_code": "EC2_Storage_Size",
	//	"region":       "ap-southeast-2",
	//	"volumeType":   "gp3",
	//})
	//if err != nil {
	//	log.Error("TestPrice", zap.Error(err))
	//	return
	//} else {
	//	log.Info("price", zap.String("price ", res.Price.String()))
	//}
	res, err := providerPriceHandler.GetPrice(map[string]string{
		"service_code": "EC2_Storage_IOPS",
		"region":       "ap-southeast-2",
		"volumeType":   "io2",
	})
	if err != nil {
		log.Error("TestPrice", zap.Error(err))
		return
	} else {
		log.Info("TestStoragePrice", zap.String("price ", res.Price.String()))
	}

}

func TestS3PriceByProductAPI(t *testing.T) {
	t.Skip()

	providerPriceHandler := &cloudproviderhandler.AwsPriceHandlerImpl{}
	serviceCode := "AmazonS3"

	c, err := providerPriceHandler.GetAwsPricingClient()
	if err != nil {
		log.Error("Failed to get AWS Pricing Client", zap.Error(err))
		return
	}
	filterRegionCode := "regionCode"
	filterRegionCodeVlaue := "us-east-1"
	filterVolumeType := "volumeType"
	filterVolumeTypeVlaue := "Standard"

	var filters []*pricing.Filter
	filters = append(filters, &pricing.Filter{
		Type:  FilterTypePtr,
		Field: &filterRegionCode,
		Value: &filterRegionCodeVlaue,
	},
		&pricing.Filter{
			Type:  FilterTypePtr,
			Field: &filterVolumeType,
			Value: &filterVolumeTypeVlaue,
		},
	)

	res, err := c.GetProducts(&pricing.GetProductsInput{
		ServiceCode: &serviceCode,
		Filters:     filters,
	})
	if err != nil {
		log.Error("Error fetching products", zap.Error(err))
		return
	}
	pp.Print(res)
	if res != nil && len(res.PriceList) > 0 {
		log.Info("res ", zap.Int("res len", len(res.PriceList)))

		for i, priceList := range res.PriceList {
			log.Info(fmt.Sprintf("PriceList %d: %s", i+1, awsutil.Prettify(priceList)))
		}
	} else {
		log.Info("No products found")
	}

	providerPriceHandler.GetPriceFromAWSRes(res.PriceList, "TimedStorage-ByteHrs", "")

}
func TestPriceByProductAPI(t *testing.T) {
	t.Skip()

	providerPriceHandler := &cloudproviderhandler.AwsPriceHandlerImpl{}
	serviceCode := "AmazonEC2"

	//	now := timeutils.GetMonthDateByYearMonth(2022, 1)

	c, err := providerPriceHandler.GetAwsPricingClient()
	if err != nil {
		log.Error("Failed to get AWS Pricing Client", zap.Error(err))
		return
	}
	filterRegionCode := "regionCode"
	filterRegionCodeVlaue := "us-east-1"
	//VolumeP-IOPS   EBS:VolumeP-IOPS.gp3
	//filterInstanceType := "instanceType"
	filterInstanceTypeVlaue := "VolumeUsage.gp3"
	filterUsagetype := "usagetype"
	filterUsagetypeVlaue := "EBS:" + filterInstanceTypeVlaue
	filterVolumeApiName := "volumeApiName"
	filterVolumeApiNameVlaue := "gp3"

	var filters []*pricing.Filter
	filters = append(filters, &pricing.Filter{
		Type:  FilterTypePtr,
		Field: &filterRegionCode,
		Value: &filterRegionCodeVlaue,
	},
		&pricing.Filter{
			Type:  FilterTypePtr,
			Field: &filterVolumeApiName,
			Value: &filterVolumeApiNameVlaue,
		},
		&pricing.Filter{
			Type:  FilterTypePtr,
			Field: &filterUsagetype,
			Value: &filterUsagetypeVlaue,
		},
	)

	res, err := c.GetProducts(&pricing.GetProductsInput{
		ServiceCode: &serviceCode,
		Filters:     filters,
	})
	if err != nil {
		log.Error("Error fetching products", zap.Error(err))
		return
	}

	if res != nil && len(res.PriceList) > 0 {
		log.Info("res ", zap.Int("res len", len(res.PriceList)))

		for i, priceList := range res.PriceList {
			log.Info(fmt.Sprintf("PriceList %d: %s", i+1, awsutil.Prettify(priceList)))
		}
	} else {
		log.Info("No products found")
	}

	providerPriceHandler.GetPriceFromAWSRes(res.PriceList, "EC2_Compute", "")

	//log.Info("Ns", zap.Any("s", priceData[0].Terms["OnDemand"][""].TermAttributes["pricePerUnit"]))

}

func TestPrice(t *testing.T) {
	t.Skip()

	providerPriceHandler := &cloudproviderhandler.AwsPriceHandlerImpl{}
	serviceCode := "AWSDataTransfer"
	currencyCode := "USD"
	regionCode := "us-west-2"
	maxResults := int64(100)
	now := timeutils.GetMonthDateByYearMonth(2022, 1)

	c, _ := providerPriceHandler.GetAwsPricingClient()

	res, err := c.ListPriceLists(&pricing.ListPriceListsInput{
		ServiceCode:   &serviceCode,
		EffectiveDate: &now,
		CurrencyCode:  &currencyCode,
		RegionCode:    &regionCode,
		MaxResults:    &maxResults,
	})
	if err != nil {
		log.Error("Error fetching price list", zap.Error(err))
	} else {
		pp.Print(res)
	}

	fileFormat := "json"
	arn := res.PriceLists[0].PriceListArn
	log.Info("arn ", zap.String("req", *arn))

	res1, err := c.GetPriceListFileUrl(&pricing.GetPriceListFileUrlInput{
		PriceListArn: arn,
		FileFormat:   &fileFormat,
	})
	if err != nil {
		log.Error("Error fetching price list", zap.Error(err))
	} else {
		log.Info("req ", zap.Any("res1", res1))
	}

	resp, err := http.Get(*res1.Url)
	if err != nil {
		log.Info("resp ", zap.Error(err))
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		log.Info("Request failed with status", zap.String("resp.Status", resp.Status))

	}
	var data map[string]interface{}
	body, err := io.ReadAll(resp.Body)
	err = json.Unmarshal(body, &data)

	fmt.Println(data)

}

func TestPriceEC2DataTransfer(t *testing.T) {
	t.Skip()

	providerPriceHandler := &cloudproviderhandler.AwsPriceHandlerImpl{}
	res, err := providerPriceHandler.GetPrice(map[string]string{
		"service_code": "Data_Transfer",
		"region":       "us-east-1",
	})
	if err != nil {
		log.Error("TestPriceEC2DataTransfer", zap.Error(err))
		return
	} else {
		log.Info("TestPriceEC2DataTransfer", zap.String("price ", res.Price.String()))
	}

}

func TestPriceFromLocal(t *testing.T) {
	t.Skip()
	filePath := "/Users/xiaowu/Downloads/index-us-east-1.json"
	file, err := os.Open(filePath)
	if err != nil {
		fmt.Println("Error opening file:", err)
		return
	}

	data, err := io.ReadAll(file)
	if err != nil {
		fmt.Println("Error reading file:", err)
		return
	}
	var awsPriceJson cloudproviderhandler.AwsPriceJson

	err = json.Unmarshal(data, &awsPriceJson)
	if err != nil {
		fmt.Println("Error unmarshaling JSON:", err)
		return
	}
	var ProductFamilyList []string
	productFamilyMap := map[string]int{}
	log.Info("wsPriceJson.Products len", zap.Int("len", len(awsPriceJson.Products)))
	for key, product := range awsPriceJson.Products {
		_, ok := productFamilyMap[product.ProductFamily]
		if ok {
			productFamilyMap[product.ProductFamily] += 1
		} else {
			productFamilyMap[product.ProductFamily] = 1
		}

		if product.ProductFamily == "System Operation" || product.ProductFamily == "Provisioned Throughput" {
			log.Info("not  Compute Instance  ", zap.Any("key", awsPriceJson.Products[key]))
			ProductFamilyList = append(ProductFamilyList, product.ProductFamily)

		}

	}
	for index, count := range productFamilyMap {
		log.Info(" productFamilyMap  ", zap.String("index", index), zap.Int("count", count))
	}

	fmt.Printf("Parsed AWS Price JSON: %+v\n", awsPriceJson.Disclaimer)
}

func TestPricePL(t *testing.T) {
	t.Skip()

	providerPriceHandler := &cloudproviderhandler.AwsPriceHandlerImpl{}
	res, err := providerPriceHandler.GetPrice(map[string]string{
		"service_code": "PrivateLink",
		"region":       "us-east-1",
	})
	if err != nil {
		log.Error("TestPricePL", zap.Error(err))
		return
	} else {
		log.Info("TestPricePL", zap.String("price ", res.Price.String()))
	}

}
func TestPriceDataTransferWithinSameRegion(t *testing.T) {
	t.Skip()

	providerPriceHandler := &cloudproviderhandler.AwsPriceHandlerImpl{}
	res, err := providerPriceHandler.GetPrice(map[string]string{
		"service_code": "Data_Transfer_Within_SameRegion",
		"region":       "ap-east-1",
	})
	if err != nil {
		log.Error("TestPriceDataTransferWithinSameRegion", zap.Error(err))
		return
	} else {
		log.Info("TestPriceDataTransferWithinSameRegion", zap.String("price ", res.Price.String()))
	}

}
func TestPriceNatGateway(t *testing.T) {
	t.Skip()

	providerPriceHandler := &cloudproviderhandler.AwsPriceHandlerImpl{}
	res, err := providerPriceHandler.GetPrice(map[string]string{
		"service_code": "NatGateway",
		"region":       "us-east-1",
	})
	if err != nil {
		log.Error("TestPriceNatGateway", zap.Error(err))
		return
	} else {
		log.Info("TestPriceNatGateway", zap.String("price ", res.Price.String()))
	}

}
func TestPriceDataTransferRegionOutMAX(t *testing.T) {
	t.Skip()

	providerPriceHandler := &cloudproviderhandler.AwsPriceHandlerImpl{}
	res, err := providerPriceHandler.GetPrice(map[string]string{
		"service_code": "Data_Transfer_RegionOut_MAX",
		"region":       "us-east-1",
	})
	if err != nil {
		log.Error("TestPriceDataTransferRegionOutMAX", zap.Error(err))
		return
	} else {
		log.Info("TestPriceDataTransferRegionOutMAX", zap.String("price ", res.Price.String()))
	}

}
func TestPriceS3RegionOutMAX(t *testing.T) {
	t.Skip()

	providerPriceHandler := &cloudproviderhandler.AwsPriceHandlerImpl{}
	res, err := providerPriceHandler.GetPrice(map[string]string{
		"service_code": "S3_RegionOut_MAX",
		"region":       "ap-east-1",
	})
	if err != nil {
		log.Error("TestPrice", zap.Error(err))
		return
	} else {
		log.Info("TestPriceS3RegionOutMAX", zap.String("price ", res.Price.String()))
	}

}
func TestNewPriceByProductAPI(t *testing.T) {
	t.Skip()

	providerPriceHandler := &cloudproviderhandler.AwsPriceHandlerImpl{}
	serviceCode := "AWSDataTransfer"

	c, err := providerPriceHandler.GetAwsPricingClient()
	if err != nil {
		log.Error("Failed to get AWS Pricing Client", zap.Error(err))
		return
	}
	filterRegionCode := "fromRegionCode"
	filterRegionCodeValue := "ap-east-1"
	filterRegionCode1 := "toRegionCode"
	filterRegionCodeValue1 := "us-west-2"
	filterType1 := "fromLocationType"
	filterValue1 := "AWS Region"

	filterType4 := "toLocationType"
	filterValue4 := "AWS Region"
	var filters []*pricing.Filter
	filters = append(filters, &pricing.Filter{
		Type:  FilterTypePtr,
		Field: &filterRegionCode,
		Value: &filterRegionCodeValue,
	},
		&pricing.Filter{
			Type:  FilterTypePtr,
			Field: &filterType1,
			Value: &filterValue1,
		},

		&pricing.Filter{
			Type:  FilterTypePtr,
			Field: &filterType4,
			Value: &filterValue4,
		},

		&pricing.Filter{
			Type:  FilterTypePtr,
			Field: &filterRegionCode1,
			Value: &filterRegionCodeValue1,
		},
	)

	res, err := c.GetProducts(&pricing.GetProductsInput{
		ServiceCode: &serviceCode,
		//	Filters:     filters,
	})
	if err != nil {
		log.Error("Error fetching products", zap.Error(err))
		return
	}
	pp.Print(res)
	if res != nil && len(res.PriceList) > 0 {
		log.Info("res ", zap.Int("res len", len(res.PriceList)))

		for i, priceList := range res.PriceList {
			log.Info(fmt.Sprintf("PriceList %d: %s", i+1, awsutil.Prettify(priceList)))
		}
	} else {
		log.Info("No products found")
	}

	providerPriceHandler.GetPriceFromAWSRes(res.PriceList, "AWS-Out-Bytes", "")

}
