// Copyright 2019 Yunion
//
// 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.

package tools

import (
	"context"
	"encoding/json"
	"fmt"
	"strconv"
	"strings"

	"github.com/mark3labs/mcp-go/mcp"

	"yunion.io/x/log"

	"yunion.io/x/onecloud/pkg/mcp-server/adapters"
	"yunion.io/x/onecloud/pkg/mcp-server/models"
)

// CloudpodsStoragesTool 用于查询Cloudpods块存储列表的工具
type CloudpodsStoragesTool struct {
	// adapter 用于与Cloudpods API进行交互
	adapter *adapters.CloudpodsAdapter
}

// NewCloudpodsStoragesTool 创建一个新的CloudpodsStoragesTool实例
//
// 参数:
//   - adapter: 用于与Cloudpods API交互的适配器
//
// 返回值:
//   - *CloudpodsStoragesTool: CloudpodsStoragesTool实例指针
func NewCloudpodsStoragesTool(adapter *adapters.CloudpodsAdapter) *CloudpodsStoragesTool {
	return &CloudpodsStoragesTool{
		adapter: adapter,
	}
}

// GetTool 定义并返回查询块存储列表工具的元数据
//
// 工具用途:
//
//	查询Cloudpods块存储列表，获取存储资源信息
//
// 参数说明:
//   - limit: 返回结果数量限制，默认为20
//   - offset: 返回结果偏移量，默认为0
//   - search: 搜索关键词，可以按存储名称搜索
//   - cloudregion_ids: 云区域ID，多个用逗号分隔
//   - zone_ids: 可用区ID，多个用逗号分隔
//   - providers: 云平台提供商，多个用逗号分隔，如：OneCloud,Aliyun,Huawei
//   - storage_types: 存储类型，多个用逗号分隔，如：local,rbd,nfs,cephfs
//   - host_id: 主机ID，过滤关联指定主机的存储
//   - ak: 用户登录cloudpods后获取的access key
//   - sk: 用户登录cloudpods后获取的secret key
func (c *CloudpodsStoragesTool) GetTool() mcp.Tool {
	return mcp.NewTool(
		"cloudpods_list_storages",
		mcp.WithDescription("查询Cloudpods块存储列表，获取存储资源信息"),
		mcp.WithString("limit", mcp.Description("返回结果数量限制，默认为20")),
		mcp.WithString("offset", mcp.Description("返回结果偏移量，默认为0")),
		mcp.WithString("search", mcp.Description("搜索关键词，可以按存储名称搜索")),
		mcp.WithString("cloudregion_ids", mcp.Description("云区域ID，多个用逗号分隔")),
		mcp.WithString("zone_ids", mcp.Description("可用区ID，多个用逗号分隔")),
		mcp.WithString("providers", mcp.Description("云平台提供商，多个用逗号分隔，如：OneCloud,Aliyun,Huawei")),
		mcp.WithString("storage_types", mcp.Description("存储类型，多个用逗号分隔，如：local,rbd,nfs,cephfs")),
		mcp.WithString("host_id", mcp.Description("主机ID，过滤关联指定主机的存储")),
		mcp.WithString("ak", mcp.Description("用户登录cloudpods后获取的access key")),
		mcp.WithString("sk", mcp.Description("用户登录cloudpods后获取的secret key")),
	)
}

// Handle 处理查询块存储列表的请求
//
// 参数:
//   - ctx: 控制生命周期的上下文
//   - req: 包含查询参数的请求对象
//
// 返回值:
//   - *mcp.CallToolResult: 包含块存储列表的响应对象
//   - error: 可能的错误信息
func (c *CloudpodsStoragesTool) Handle(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
	// 获取可选参数：返回结果数量限制，如果指定则转换为整数
	limit := 20
	if limitStr := req.GetString("limit", ""); limitStr != "" {
		if parsedLimit, err := strconv.Atoi(limitStr); err == nil && parsedLimit > 0 {
			limit = parsedLimit
		}
	}

	// 获取可选参数：结果偏移量，如果指定则转换为整数
	offset := 0
	if offsetStr := req.GetString("offset", ""); offsetStr != "" {
		if parsedOffset, err := strconv.Atoi(offsetStr); err == nil && parsedOffset >= 0 {
			offset = parsedOffset
		}
	}

	// 获取可选参数：搜索关键词
	search := req.GetString("search", "")

	// 获取可选参数：云区域ID列表
	var cloudregionIds []string
	if cloudregionIdsStr := req.GetString("cloudregion_ids", ""); cloudregionIdsStr != "" {
		cloudregionIds = strings.Split(cloudregionIdsStr, ",")
		for i, id := range cloudregionIds {
			cloudregionIds[i] = strings.TrimSpace(id)
		}
	}

	// 获取可选参数：可用区ID列表
	var zoneIds []string
	if zoneIdsStr := req.GetString("zone_ids", ""); zoneIdsStr != "" {
		zoneIds = strings.Split(zoneIdsStr, ",")
		for i, id := range zoneIds {
			zoneIds[i] = strings.TrimSpace(id)
		}
	}

	// 获取可选参数：云平台提供商列表
	var providers []string
	if providersStr := req.GetString("providers", ""); providersStr != "" {
		providers = strings.Split(providersStr, ",")
		for i, provider := range providers {
			providers[i] = strings.TrimSpace(provider)
		}
	}

	// 获取可选参数：存储类型列表
	var storageTypes []string
	if storageTypesStr := req.GetString("storage_types", ""); storageTypesStr != "" {
		storageTypes = strings.Split(storageTypesStr, ",")
		for i, storageType := range storageTypes {
			storageTypes[i] = strings.TrimSpace(storageType)
		}
	}

	// 获取可选参数：主机ID
	hostId := req.GetString("host_id", "")

	// 获取可选参数：访问凭证
	ak := req.GetString("ak", "")
	sk := req.GetString("sk", "")

	// 调用适配器查询块存储列表
	storagesResponse, err := c.adapter.ListStorages(ctx, limit, offset, search, cloudregionIds, zoneIds, providers, storageTypes, hostId, ak, sk)
	if err != nil {
		log.Errorf("Fail to query storage: %s", err)
		return nil, fmt.Errorf("fail to query storage: %w", err)
	}

	// 格式化查询结果
	formattedResult := c.formatStoragesResult(storagesResponse, limit, offset, search, cloudregionIds, zoneIds, providers, storageTypes, hostId)

	// 将结果序列化为JSON格式
	resultJSON, err := json.MarshalIndent(formattedResult, "", "  ")
	if err != nil {
		log.Errorf("Fail to serialize result: %s", err)
		return nil, fmt.Errorf("fail to serialize result: %w", err)
	}

	return mcp.NewToolResultText(string(resultJSON)), nil
}

// GetName 返回工具的名称标识符
//
// 返回值:
//   - string: 工具名称字符串，用于唯一标识该工具
func (c *CloudpodsStoragesTool) GetName() string {
	return "cloudpods_list_storages"
}

// formatStoragesResult 格式化块存储列表的响应结果
//
// 参数:
//   - response: 原始响应数据
//   - limit: 查询限制
//   - offset: 查询偏移量
//   - search: 搜索关键词
//   - cloudregionIds: 云区域ID列表
//   - zoneIds: 可用区ID列表
//   - providers: 云平台提供商列表
//   - storageTypes: 存储类型列表
//   - hostId: 主机ID
//
// 返回值:
//   - map[string]interface{}: 包含块存储列表的格式化结果
func (c *CloudpodsStoragesTool) formatStoragesResult(
	response *models.StorageListResponse,
	limit, offset int,
	search string,
	cloudregionIds, zoneIds, providers, storageTypes []string,
	hostId string,
) map[string]interface{} {
	// 初始化格式化结果结构
	formatted := map[string]interface{}{
		"query_info": map[string]interface{}{
			"limit":           limit,
			"offset":          offset,
			"search":          search,
			"cloudregion_ids": cloudregionIds,
			"zone_ids":        zoneIds,
			"providers":       providers,
			"storage_types":   storageTypes,
			"host_id":         hostId,
			"total":           response.Total,
			"count":           len(response.Storages),
		},
		"storages": make([]map[string]interface{}, 0, len(response.Storages)),
	}

	// 遍历块存储列表，构造每个块存储的详细信息
	for _, storage := range response.Storages {
		capacityGB := float64(storage.Capacity) / 1024
		usedCapacityGB := float64(storage.UsedCapacity) / 1024
		freeCapacityGB := float64(storage.FreeCapacity) / 1024
		actualUsedGB := float64(storage.ActualCapacityUsed) / 1024

		storageInfo := map[string]interface{}{
			"id":                    storage.Id,
			"name":                  storage.Name,
			"description":           storage.Description,
			"status":                storage.Status,
			"enabled":               storage.Enabled,
			"storage_type":          storage.StorageType,
			"medium_type":           storage.MediumType,
			"provider":              storage.Provider,
			"brand":                 storage.Brand,
			"cloud_env":             storage.CloudEnv,
			"cloudregion":           storage.Cloudregion,
			"cloudregion_id":        storage.CloudregionId,
			"zone":                  storage.Zone,
			"zone_id":               storage.ZoneId,
			"zone_ext_id":           storage.ZoneExtId,
			"capacity_mb":           storage.Capacity,
			"capacity_gb":           fmt.Sprintf("%.2f GB", capacityGB),
			"used_capacity_mb":      storage.UsedCapacity,
			"used_capacity_gb":      fmt.Sprintf("%.2f GB", usedCapacityGB),
			"free_capacity_mb":      storage.FreeCapacity,
			"free_capacity_gb":      fmt.Sprintf("%.2f GB", freeCapacityGB),
			"actual_capacity_used":  storage.ActualCapacityUsed,
			"actual_used_gb":        fmt.Sprintf("%.2f GB", actualUsedGB),
			"virtual_capacity":      storage.VirtualCapacity,
			"waste_capacity":        storage.WasteCapacity,
			"reserved":              storage.Reserved,
			"commit_bound":          storage.CommitBound,
			"commit_rate":           storage.CommitRate,
			"cmtbound":              storage.Cmtbound,
			"is_sys_disk_store":     storage.IsSysDiskStore,
			"is_public":             storage.IsPublic,
			"is_emulated":           storage.IsEmulated,
			"disk_count":            storage.DiskCount,
			"host_count":            storage.HostCount,
			"snapshot_count":        storage.SnapshotCount,
			"master_host":           storage.MasterHost,
			"master_host_name":      storage.MasterHostName,
			"storagecache_id":       storage.StoragecacheId,
			"account":               storage.Account,
			"account_id":            storage.AccountId,
			"account_status":        storage.AccountStatus,
			"account_health_status": storage.AccountHealthStatus,
			"account_read_only":     storage.AccountReadOnly,
			"manager":               storage.Manager,
			"manager_id":            storage.ManagerId,
			"manager_domain":        storage.ManagerDomain,
			"manager_domain_id":     storage.ManagerDomainId,
			"manager_project":       storage.ManagerProject,
			"manager_project_id":    storage.ManagerProjectId,
			"external_id":           storage.ExternalId,
			"source":                storage.Source,
			"region":                storage.Region,
			"region_id":             storage.RegionId,
			"region_ext_id":         storage.RegionExtId,
			"region_external_id":    storage.RegionExternalId,
			"environment":           storage.Environment,
			"domain_id":             storage.DomainId,
			"domain_src":            storage.DomainSrc,
			"project_domain":        storage.ProjectDomain,
			"public_scope":          storage.PublicScope,
			"public_src":            storage.PublicSrc,
			"shared_domains":        storage.SharedDomains,
			"shared_projects":       storage.SharedProjects,
			"schedtags":             storage.Schedtags,
			"hosts":                 storage.Hosts,
			"storage_conf":          storage.StorageConf,
			"metadata":              storage.Metadata,
			"progress":              storage.Progress,
			"can_delete":            storage.CanDelete,
			"can_update":            storage.CanUpdate,
			"update_version":        storage.UpdateVersion,
			"created_at":            storage.CreatedAt,
			"updated_at":            storage.UpdatedAt,
			"imported_at":           storage.ImportedAt,
		}
		formatted["storages"] = append(formatted["storages"].([]map[string]interface{}), storageInfo)
	}

	// 构造摘要信息
	formatted["summary"] = map[string]interface{}{
		"total_storages": response.Total,                                        // 总存储数量
		"returned_count": len(response.Storages),                                // 当前返回的存储数量
		"has_more":       response.Total > int64(offset+len(response.Storages)), // 是否还有更多数据
		"next_offset":    offset + len(response.Storages),                       // 下一页的偏移量
	}

	return formatted
}
