package oci

import (
	"fmt"
	"strings"
)

// Credentials 是调用 OCI API 所需的完整凭据，私钥为 PEM 明文。
// CompartmentID 限定资源操作的目标 compartment，空表示租户根；
// 只影响 compute / 网络 / 块存储等资源查询，身份与订阅类调用始终走租户根。
type Credentials struct {
	TenancyOCID   string
	UserOCID      string
	Region        string
	Fingerprint   string
	PrivateKey    string
	Passphrase    string
	CompartmentID string
	// Proxy 非 nil 时该租户全部 SDK 出站请求经此代理
	Proxy *ProxySpec
}

// EffectiveCompartment 返回资源操作的目标 compartment，未指定时为租户根。
func (c Credentials) EffectiveCompartment() *string {
	if c.CompartmentID != "" {
		id := c.CompartmentID
		return &id
	}
	id := c.TenancyOCID
	return &id
}

// Validate 检查凭据必填字段。
func (c Credentials) Validate() error {
	switch {
	case c.TenancyOCID == "":
		return fmt.Errorf("credentials: tenancy is empty")
	case c.UserOCID == "":
		return fmt.Errorf("credentials: user is empty")
	case c.Region == "":
		return fmt.Errorf("credentials: region is empty")
	case c.Fingerprint == "":
		return fmt.Errorf("credentials: fingerprint is empty")
	case !strings.Contains(c.PrivateKey, "PRIVATE KEY"):
		return fmt.Errorf("credentials: private key is not a PEM")
	}
	return nil
}

// ParseConfigINI 解析 OCI 标准 config（ini）文本的 [DEFAULT] 段。
// key_file 只在本机指向文件，导入场景私钥内容必须单独提供，因此忽略该行。
func ParseConfigINI(text string) (Credentials, error) {
	var cred Credentials
	section := "DEFAULT"
	for _, line := range strings.Split(text, "\n") {
		line = strings.TrimSpace(line)
		if line == "" || strings.HasPrefix(line, "#") || strings.HasPrefix(line, ";") {
			continue
		}
		if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
			section = strings.TrimSpace(line[1 : len(line)-1])
			continue
		}
		if !strings.EqualFold(section, "DEFAULT") {
			continue
		}
		applyConfigLine(&cred, line)
	}
	if cred.TenancyOCID == "" && cred.UserOCID == "" {
		return cred, fmt.Errorf("parse oci config: no recognizable fields")
	}
	return cred, nil
}

func applyConfigLine(cred *Credentials, line string) {
	key, value, ok := strings.Cut(line, "=")
	if !ok {
		return
	}
	// OCID、指纹、region 值里不含 #，可安全去掉行尾注释
	if i := strings.Index(value, "#"); i >= 0 {
		value = value[:i]
	}
	key = strings.TrimSpace(strings.ToLower(key))
	value = strings.TrimSpace(value)
	switch key {
	case "user":
		cred.UserOCID = value
	case "tenancy":
		cred.TenancyOCID = value
	case "fingerprint":
		cred.Fingerprint = value
	case "region":
		cred.Region = value
	case "pass_phrase":
		cred.Passphrase = value
	}
}
