/**
 * Content Reference System Types
 *
 * Shared interfaces for the Reference-Based Content System that handles
 * large content storage with unique reference IDs to optimize context window usage.
 */

/**
 * Unique identifier for stored content references
 * Format: Cryptographically secure 32-byte identifier with base64url encoding
 */
export type ReferenceId = string;

/**
 * Lifecycle state of a content reference
 */
export type ReferenceLifecycleState =
  | 'active'
  | 'expired'
  | 'cleanup_pending'
  | 'invalid';

/**
 * Content types supported by the reference system
 */
export type ContentType =
  | 'text'
  | 'json'
  | 'html'
  | 'markdown'
  | 'binary'
  | 'unknown';

/**
 * Sources that created the content reference
 */
export type ContentSource =
  | 'mcp_tool'
  | 'user_upload'
  | 'agent_generated'
  | 'system';

/**
 * Metadata associated with stored content
 */
export interface ContentMetadata {
  /** Content type classification */
  contentType: ContentType;

  /** MIME type of the original content */
  mimeType?: string;

  /** Size in bytes of the stored content */
  sizeBytes: number;

  /** When the content was originally stored */
  createdAt: Date;

  /** Last time the content was accessed via reference resolution */
  lastAccessedAt: Date;

  /** Source that created this content reference */
  source: ContentSource;

  /** Name of the MCP tool that generated the content (if applicable) */
  mcpToolName?: string;

  /** Original filename or suggested name for the content */
  fileName?: string;

  /** Number of times this reference has been resolved */
  accessCount: number;

  /** Tags for categorization and cleanup policies */
  tags?: string[];

  /** Custom metadata from the source */
  customMetadata?: Record<string, unknown>;
}

/**
 * Core content reference object passed through agent context
 * Designed to be lightweight (<100 tokens) while providing enough
 * information for agent decision-making
 */
export interface ContentReference {
  /** Unique identifier for resolving the content */
  referenceId: ReferenceId;

  /** Current lifecycle state */
  state: ReferenceLifecycleState;

  /** Brief description or preview of the content (max 200 chars) */
  preview: string;

  /** Essential metadata for agent decision-making */
  metadata: Pick<
    ContentMetadata,
    'contentType' | 'sizeBytes' | 'source' | 'fileName' | 'mimeType'
  >;

  /** When this reference was created */
  createdAt: Date;

  /** Special format indicator for reference IDs in content */
  readonly format: 'ref://{id}';
}

/**
 * Result of attempting to resolve a content reference
 */
export interface ReferenceResolutionResult {
  /** Whether the resolution was successful */
  success: boolean;

  /** The resolved content if successful */
  content?: Buffer;

  /** Complete metadata if successful */
  metadata?: ContentMetadata;

  /** Error message if resolution failed */
  error?: string;

  /** Specific error type for targeted error handling */
  errorType?:
    | 'not_found'
    | 'expired'
    | 'corrupted'
    | 'access_denied'
    | 'system_error';

  /** Suggested actions for recovery */
  suggestedActions?: string[];
}

/**
 * Configuration for content reference storage and lifecycle
 */
export interface ContentReferenceConfig {
  /** Size threshold above which content should be stored as references (default: 10KB) */
  sizeThresholdBytes: number;

  /** Maximum age for unused references before cleanup (default: 1 hour) */
  maxAgeMs: number;

  /** Maximum number of references to store simultaneously */
  maxReferences: number;

  /** Maximum total storage size for all references */
  maxTotalStorageBytes: number;

  /** Whether to enable automatic cleanup */
  enableAutoCleanup: boolean;

  /** Interval for cleanup checks in milliseconds */
  cleanupIntervalMs: number;

  /** Whether to persist references across restarts */
  enablePersistence: boolean;

  /** Storage backend configuration */
  storageBackend: 'memory' | 'filesystem' | 'hybrid';

  /** Cleanup policies for different content types */
  cleanupPolicies: {
    /** Policy for content marked as "recent" from MCP tools */
    recent: { maxAgeMs: number; priority: number };

    /** Policy for user-uploaded content */
    userContent: { maxAgeMs: number; priority: number };

    /** Policy for agent-generated content */
    agentGenerated: { maxAgeMs: number; priority: number };

    /** Default policy for other content */
    default: { maxAgeMs: number; priority: number };
  };
}

/**
 * Default configuration values
 */
export const DEFAULT_CONTENT_REFERENCE_CONFIG: ContentReferenceConfig = {
  sizeThresholdBytes: 10 * 1024,
  maxAgeMs: 60 * 60 * 1000,
  maxReferences: 100,
  maxTotalStorageBytes: 100 * 1024 * 1024,
  enableAutoCleanup: true,
  cleanupIntervalMs: 5 * 60 * 1000,
  enablePersistence: false,
  storageBackend: 'memory',
  cleanupPolicies: {
    recent: { maxAgeMs: 30 * 60 * 1000, priority: 1 },
    userContent: { maxAgeMs: 2 * 60 * 60 * 1000, priority: 2 },
    agentGenerated: { maxAgeMs: 60 * 60 * 1000, priority: 3 },
    default: { maxAgeMs: 60 * 60 * 1000, priority: 4 },
  },
};

/**
 * Statistics about content reference usage and storage
 */
export interface ContentReferenceStats {
  /** Total number of active references */
  activeReferences: number;

  /** Total storage used by all references in bytes */
  totalStorageBytes: number;

  /** Number of references cleaned up in last cleanup cycle */
  recentlyCleanedUp: number;

  /** Number of successful reference resolutions since startup */
  totalResolutions: number;

  /** Number of failed resolution attempts */
  failedResolutions: number;

  /** Average content size in bytes */
  averageContentSize: number;

  /** Most frequently accessed reference ID */
  mostAccessedReferenceId?: ReferenceId;

  /** Storage utilization percentage */
  storageUtilization: number;

  /** Performance metrics */
  performanceMetrics: {
    /** Average time to create a reference in milliseconds */
    averageCreationTimeMs: number;

    /** Average time to resolve a reference in milliseconds */
    averageResolutionTimeMs: number;

    /** Average cleanup time in milliseconds */
    averageCleanupTimeMs: number;
  };
}

/**
 * Error types for content reference operations
 */
export class ContentReferenceError extends Error {
  constructor(
    message: string,
    public readonly type: ReferenceResolutionResult['errorType'],
    public readonly referenceId?: ReferenceId,
    public readonly suggestedActions?: string[]
  ) {
    super(message);
    this.name = 'ContentReferenceError';
  }
}

/**
 * Interface for content reference storage implementations
 */
export interface ContentReferenceStore {
  /**
   * Store content and return a reference
   */
  storeContent(
    content: Buffer,
    metadata: Omit<
      ContentMetadata,
      'createdAt' | 'lastAccessedAt' | 'accessCount'
    >
  ): Promise<ContentReference>;

  /**
   * Resolve a reference to its content
   */
  resolveReference(
    referenceId: ReferenceId
  ): Promise<ReferenceResolutionResult>;

  /**
   * Check if a reference exists and is valid
   */
  hasReference(referenceId: ReferenceId): Promise<boolean>;

  /**
   * Mark a reference for cleanup
   */
  cleanupReference(referenceId: ReferenceId): Promise<boolean>;

  /**
   * Get current storage statistics
   */
  getStats(): Promise<ContentReferenceStats>;

  /**
   * Update configuration
   */
  updateConfig(config: Partial<ContentReferenceConfig>): Promise<void>;

  /**
   * Perform cleanup based on current policies
   */
  performCleanup(): Promise<{ cleanedUp: number; errors: string[] }>;

  /**
   * Dispose of resources
   */
  dispose(): Promise<void>;
}
