// Package logging configures the gateway structured logger and provides
// context-aware helpers for attaching OpenTelemetry trace identifiers.
package logging

import (
	"context"
	"strings"

	"galaxy/gateway/internal/config"

	"go.opentelemetry.io/otel/trace"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

// New constructs the process-wide JSON logger from cfg.
func New(cfg config.LoggingConfig) (*zap.Logger, error) {
	level := zap.NewAtomicLevel()
	if err := level.UnmarshalText([]byte(strings.TrimSpace(cfg.Level))); err != nil {
		return nil, err
	}

	zapCfg := zap.NewProductionConfig()
	zapCfg.Level = level
	zapCfg.Sampling = nil
	zapCfg.Encoding = "json"
	zapCfg.EncoderConfig.TimeKey = "timestamp"
	zapCfg.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	zapCfg.OutputPaths = []string{"stdout"}
	zapCfg.ErrorOutputPaths = []string{"stderr"}

	return zapCfg.Build()
}

// TraceFieldsFromContext returns zap fields for the active OpenTelemetry span
// when ctx carries a valid span context.
func TraceFieldsFromContext(ctx context.Context) []zap.Field {
	if ctx == nil {
		return nil
	}

	spanContext := trace.SpanContextFromContext(ctx)
	if !spanContext.IsValid() {
		return nil
	}

	return []zap.Field{
		zap.String("otel_trace_id", spanContext.TraceID().String()),
		zap.String("otel_span_id", spanContext.SpanID().String()),
	}
}

// Sync flushes logger and ignores the benign stdout or stderr sync errors
// commonly returned by containerized or redirected process outputs.
func Sync(logger *zap.Logger) error {
	if logger == nil {
		return nil
	}

	err := logger.Sync()
	if err == nil || isIgnorableSyncError(err) {
		return nil
	}

	return err
}

func isIgnorableSyncError(err error) bool {
	if err == nil {
		return false
	}

	message := strings.ToLower(err.Error())
	switch {
	case strings.Contains(message, "invalid argument"):
		return true
	case strings.Contains(message, "bad file descriptor"):
		return true
	case strings.Contains(message, "inappropriate ioctl for device"):
		return true
	default:
		return false
	}
}
