package transport

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"sync"

	"omnisocketgo/cmd/internal/protocol"
)

const (
	txTimestampDebugRecordTypeSendChunk     = "send_chunk"
	txTimestampDebugRecordTypeErrqueueEvent = "errqueue_event"
)

// TXTimestampDebugRecord 是 TX errqueue 调试日志的一条 JSONL 记录。
type TXTimestampDebugRecord struct {
	RecordType  string               `json:"record_type"`
	NodeRole    string               `json:"node_role,omitempty"`
	NodeID      string               `json:"node_id,omitempty"`
	MessageType protocol.MessageType `json:"message_type"`
	MessageID   uint64               `json:"message_id"`
	From        string               `json:"from"`
	To          string               `json:"to"`
	FileName    string               `json:"file_name,omitempty"`
	BodySize    int                  `json:"body_size"`

	Phase                string  `json:"phase,omitempty"`
	SendCallIndex        *int    `json:"send_call_index,omitempty"`
	FrameOffsetStart     *int    `json:"frame_offset_start,omitempty"`
	FrameOffsetEnd       *int    `json:"frame_offset_end,omitempty"`
	BytesWritten         *int    `json:"bytes_written,omitempty"`
	ExpectedTXID         *uint32 `json:"expected_tx_id,omitempty"`
	ReadIndex            *int    `json:"read_index,omitempty"`
	EventName            string  `json:"event_name,omitempty"`
	TSUnixNano           *int64  `json:"ts_unix_nano,omitempty"`
	EEInfo               *uint32 `json:"ee_info,omitempty"`
	EEData               *uint32 `json:"ee_data,omitempty"`
	MatchedSendCallIndex *int    `json:"matched_send_call_index,omitempty"`
	SelectedForLatency   *bool   `json:"selected_for_latency,omitempty"`
}

// TXTimestampDebugLogger 接收 TX errqueue 调试记录。
type TXTimestampDebugLogger interface {
	LogTXTimestampDebugRecord(record TXTimestampDebugRecord) error
}

// JSONLTXTimestampDebugLogger 以 JSONL 形式追加写 TX errqueue 调试日志。
type JSONLTXTimestampDebugLogger struct {
	mu        sync.Mutex
	closeOnce sync.Once
	closeErr  error
	file      *os.File
}

// NewJSONLTXTimestampDebugLogger 创建一个线程安全的 TX errqueue JSONL 日志器。
func NewJSONLTXTimestampDebugLogger(path string) (*JSONLTXTimestampDebugLogger, error) {
	dir := filepath.Dir(path)
	if err := os.MkdirAll(dir, 0o755); err != nil {
		return nil, fmt.Errorf("transport: create tx timestamp debug log dir %s: %w", dir, err)
	}

	file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o644)
	if err != nil {
		return nil, fmt.Errorf("transport: open tx timestamp debug log %s: %w", path, err)
	}

	return &JSONLTXTimestampDebugLogger{file: file}, nil
}

// LogTXTimestampDebugRecord 以单行 JSON 的形式追加一条调试记录。
func (l *JSONLTXTimestampDebugLogger) LogTXTimestampDebugRecord(record TXTimestampDebugRecord) error {
	line, err := json.Marshal(record)
	if err != nil {
		return err
	}

	l.mu.Lock()
	defer l.mu.Unlock()

	if _, err := l.file.Write(append(line, '\n')); err != nil {
		return err
	}

	return nil
}

// Close 关闭底层文件；重复调用是安全的。
func (l *JSONLTXTimestampDebugLogger) Close() error {
	l.closeOnce.Do(func() {
		l.closeErr = l.file.Close()
	})

	return l.closeErr
}
