package main

import (
	"context"
	"crypto/tls"
	"log"
	"time"

	pb "bsm/full/module/base/initial/pb"
	"git.apinb.com/bsm-sdk/core/utils"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/credentials/insecure"
	"google.golang.org/grpc/metadata"
)

const (
	address = "api.apinb.com:10020" // 本地测试地址
)

func main() {
	log.Println("开始测试 Initial Service...")

	// 测试健康检查
	testHello()

	// 测试配置获取
	testConfig()

	// 测试更新检查
	testUpdates()

	// 测试国家数据
	testCountry()

	// 测试地区数据
	testAreas()

	// 测试系统数据
	testDatas()

	log.Println("所有测试完成!")
}

// 创建gRPC连接
func createConnection() (*grpc.ClientConn, error) {
	// 使用不安全连接进行本地测试
	conn, err := grpc.Dial(address,
		grpc.WithTransportCredentials(insecure.NewCredentials()),
		grpc.WithBlock(),
	)
	return conn, err
}

// 创建带有TLS的连接（用于生产环境）
func createSecureConnection() (*grpc.ClientConn, error) {
	config := &tls.Config{
		ServerName: "api.apinb.com",
	}
	conn, err := grpc.Dial("api.apinb.com:443",
		grpc.WithTransportCredentials(credentials.NewTLS(config)),
		grpc.WithBlock(),
	)
	return conn, err
}

// 创建上下文和元数据
func createContext() (context.Context, context.CancelFunc) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)

	newMetaData := metadata.New(nil)
	newMetaData.Set("request_id", utils.UUID())
	newMetaData.Set("workspace", "bsm")
	outCtx := metadata.NewOutgoingContext(ctx, newMetaData)

	return outCtx, cancel
}

// 测试健康检查
func testHello() {
	log.Println("测试健康检查...")

	conn, err := createConnection()
	if err != nil {
		log.Printf("连接失败: %v", err)
		return
	}
	defer conn.Close()

	client := pb.NewCheckClient(conn)
	ctx, cancel := createContext()
	defer cancel()

	resp, err := client.Hello(ctx, &pb.Crc{Code: "test"})
	if err != nil {
		log.Printf("Hello 调用失败: %v", err)
		return
	}
	log.Printf("Hello 响应: %v", resp)
}

// 测试配置获取
func testConfig() {
	log.Println("测试配置获取...")

	conn, err := createConnection()
	if err != nil {
		log.Printf("连接失败: %v", err)
		return
	}
	defer conn.Close()

	client := pb.NewCheckClient(conn)
	ctx, cancel := createContext()
	defer cancel()

	resp, err := client.Config(ctx, &pb.ConfigRequest{
		App: "test-app",
		Os:  "linux",
	})
	if err != nil {
		log.Printf("Config 调用失败: %v", err)
		return
	}
	log.Printf("Config 响应: %v", resp)
}

// 测试更新检查
func testUpdates() {
	log.Println("测试更新检查...")

	conn, err := createConnection()
	if err != nil {
		log.Printf("连接失败: %v", err)
		return
	}
	defer conn.Close()

	client := pb.NewCheckClient(conn)
	ctx, cancel := createContext()
	defer cancel()

	resp, err := client.Updates(ctx, &pb.CheckForUpdatesRequest{
		App:     "test-app",
		Os:      "linux",
		Arch:    "amd64",
		Version: "1.0.0",
	})
	if err != nil {
		log.Printf("Updates 调用失败: %v", err)
		return
	}
	log.Printf("Updates 响应: %v", resp)
}

// 测试国家数据
func testCountry() {
	log.Println("测试国家数据...")

	conn, err := createConnection()
	if err != nil {
		log.Printf("连接失败: %v", err)
		return
	}
	defer conn.Close()

	client := pb.NewDataClient(conn)
	ctx, cancel := createContext()
	defer cancel()

	resp, err := client.Country(ctx, &pb.Empty{})
	if err != nil {
		log.Printf("Country 调用失败: %v", err)
		return
	}
	log.Printf("Country 响应: 共 %d 个国家", len(resp.Countries))
}

// 测试地区数据
func testAreas() {
	log.Println("测试地区数据...")

	conn, err := createConnection()
	if err != nil {
		log.Printf("连接失败: %v", err)
		return
	}
	defer conn.Close()

	client := pb.NewDataClient(conn)
	ctx, cancel := createContext()
	defer cancel()

	resp, err := client.Areas(ctx, &pb.AreasRequest{
		CountryId: 1, // 中国
		ShowTown:  false,
	})
	if err != nil {
		log.Printf("Areas 调用失败: %v", err)
		return
	}
	log.Printf("Areas 响应: 共 %d 个地区", len(resp.Areas))
}

// 测试系统数据
func testDatas() {
	log.Println("测试系统数据...")

	conn, err := createConnection()
	if err != nil {
		log.Printf("连接失败: %v", err)
		return
	}
	defer conn.Close()

	client := pb.NewDataClient(conn)
	ctx, cancel := createContext()
	defer cancel()

	resp, err := client.Datas(ctx, &pb.Empty{})
	if err != nil {
		log.Printf("Datas 调用失败: %v", err)
		return
	}
	log.Printf("Datas 响应: 共 %d 个数据项", len(resp.Datas))
}
