package internal

import (
	"encoding/json"
	"fmt"
	"strings"
)

// DNSNode represents a DNS record.
// http://95.128.3.201:8053/API/NSService_10#DNSNode
type DNSNode struct {
	Name string `json:"name"`
	Type string `json:"type"`
	Data string `json:"data"`
	TTL  int    `json:"ttl"`
}

// DNSZone represents a DNS zone.
// http://95.128.3.201:8053/API/NSService_10#DNSZone
type DNSZone struct {
	Name string `json:"name,omitempty"`
	View string `json:"view,omitempty"`
}

// APIRequest represents a JSON-RPC request.
// https://www.jsonrpc.org/specification_v1#a1.1Requestmethodinvocation
type APIRequest struct {
	ID     any    `json:"id"` // Can be int or string depending on API
	Method string `json:"method"`
	Params []any  `json:"params"`
}

// APIResponse represents a JSON-RPC response.
// https://www.jsonrpc.org/specification_v1#a1.2Response
type APIResponse struct {
	ID     any             `json:"id"` // Can be int or string depending on API
	Result json.RawMessage `json:"result"`
	Error  *APIError       `json:"error"`
}

// APIError represents an error.
type APIError struct {
	Code       any      `json:"code"` // Can be int or string depending on API
	Filename   string   `json:"filename"`
	LineNumber int      `json:"lineno"`
	Message    string   `json:"string"`
	Detail     []string `json:"detail"`
}

func (e *APIError) Error() string {
	msg := new(strings.Builder)

	_, _ = fmt.Fprintf(msg, "code: %v", e.Code)

	if e.Filename != "" {
		_, _ = fmt.Fprintf(msg, ", filename: %s", e.Filename)
	}

	if e.LineNumber > 0 {
		_, _ = fmt.Fprintf(msg, ", line: %d", e.LineNumber)
	}

	if e.Message != "" {
		_, _ = fmt.Fprintf(msg, ", message: %s", e.Message)
	}

	if len(e.Detail) > 0 {
		_, _ = fmt.Fprintf(msg, ", detail: %v", strings.Join(e.Detail, " "))
	}

	return msg.String()
}
