/**
 * V2 Shared Workspace Type Definitions
 *
 * A Workspace is a structured, versioned JSON document that agents can
 * read and write. Optimistic locking (CAS — Compare-And-Swap) ensures
 * consistency: writes must include the expectedVersion, and fail with
 * a conflict if another writer has updated the document since the read.
 *
 * Usage discipline (CEO requirement):
 * - Each workspace has an owner (agent/team/system)
 * - Schema defines allowed structure
 * - Access mode controls append vs overwrite
 * - Ownership prevents unauthorized writes
 *
 * @module types/v2/workspace.types
 */
import { v4 as uuidv4 } from 'uuid';
/** All valid access modes. */
export const WORKSPACE_ACCESS_MODES = [
    'overwrite',
    'append',
    'structured',
];
/** All valid owner types. */
export const WORKSPACE_OWNER_TYPES = [
    'agent',
    'team',
    'mission',
    'system',
];
// ---------------------------------------------------------------------------
// CAS Error
// ---------------------------------------------------------------------------
/**
 * Error thrown when a CAS conflict occurs.
 * The client's expectedVersion doesn't match the current version.
 */
export class WorkspaceConflictError extends Error {
    workspaceId;
    expectedVersion;
    actualVersion;
    constructor(workspaceId, expectedVersion, actualVersion) {
        super(`Workspace conflict: expected version ${expectedVersion} but current is ${actualVersion}`);
        this.name = 'WorkspaceConflictError';
        this.workspaceId = workspaceId;
        this.expectedVersion = expectedVersion;
        this.actualVersion = actualVersion;
    }
}
/**
 * Error thrown when a writer is not authorized.
 */
export class WorkspaceAccessError extends Error {
    workspaceId;
    writerId;
    constructor(workspaceId, writerId) {
        super(`Access denied: '${writerId}' is not authorized to write to workspace '${workspaceId}'`);
        this.name = 'WorkspaceAccessError';
        this.workspaceId = workspaceId;
        this.writerId = writerId;
    }
}
// ---------------------------------------------------------------------------
// Type Guards
// ---------------------------------------------------------------------------
/**
 * Checks whether a string is a valid WorkspaceAccessMode.
 */
export function isValidWorkspaceAccessMode(value) {
    return WORKSPACE_ACCESS_MODES.includes(value);
}
/**
 * Checks whether a string is a valid WorkspaceOwnerType.
 */
export function isValidWorkspaceOwnerType(value) {
    return WORKSPACE_OWNER_TYPES.includes(value);
}
/**
 * Validates that an unknown value is structurally a valid Workspace.
 */
export function isWorkspace(value) {
    if (typeof value !== 'object' || value === null)
        return false;
    const obj = value;
    return (typeof obj.id === 'string' &&
        typeof obj.name === 'string' &&
        typeof obj.ownerType === 'string' &&
        isValidWorkspaceOwnerType(obj.ownerType) &&
        typeof obj.ownerId === 'string' &&
        typeof obj.accessMode === 'string' &&
        isValidWorkspaceAccessMode(obj.accessMode) &&
        typeof obj.data === 'object' && obj.data !== null &&
        typeof obj.version === 'number' && obj.version >= 1 &&
        Array.isArray(obj.allowedWriters) &&
        typeof obj.createdAt === 'string' &&
        typeof obj.updatedAt === 'string');
}
// ---------------------------------------------------------------------------
// Validation
// ---------------------------------------------------------------------------
/**
 * Validates CreateWorkspaceInput.
 *
 * @param input - The creation input to validate
 * @returns Array of validation error strings (empty = valid)
 */
export function validateCreateWorkspaceInput(input) {
    const errors = [];
    if (!input.name || typeof input.name !== 'string') {
        errors.push('name is required and must be a non-empty string');
    }
    if (!input.ownerType || !isValidWorkspaceOwnerType(input.ownerType)) {
        errors.push(`ownerType must be one of: ${WORKSPACE_OWNER_TYPES.join(', ')}`);
    }
    if (!input.ownerId || typeof input.ownerId !== 'string') {
        errors.push('ownerId is required and must be a non-empty string');
    }
    if (input.accessMode && !isValidWorkspaceAccessMode(input.accessMode)) {
        errors.push(`accessMode must be one of: ${WORKSPACE_ACCESS_MODES.join(', ')}`);
    }
    return errors;
}
/**
 * Validates WriteWorkspaceInput.
 */
export function validateWriteWorkspaceInput(input) {
    const errors = [];
    if (typeof input.expectedVersion !== 'number' || input.expectedVersion < 1) {
        errors.push('expectedVersion must be a positive integer');
    }
    if (typeof input.data !== 'object' || input.data === null) {
        errors.push('data must be a non-null object');
    }
    if (!input.writerId || typeof input.writerId !== 'string') {
        errors.push('writerId is required and must be a non-empty string');
    }
    return errors;
}
// ---------------------------------------------------------------------------
// Factory
// ---------------------------------------------------------------------------
/**
 * Creates a new Workspace with sensible defaults.
 *
 * @param input - Required and optional creation fields
 * @returns A fully populated Workspace at version 1
 *
 * @example
 * ```typescript
 * const ws = createWorkspace({
 *   name: 'Sprint 1 Results',
 *   ownerType: 'team',
 *   ownerId: 'team-product',
 * });
 * ```
 */
export function createWorkspace(input) {
    const now = new Date().toISOString();
    return {
        id: uuidv4(),
        name: input.name,
        description: input.description,
        ownerType: input.ownerType,
        ownerId: input.ownerId,
        accessMode: input.accessMode ?? 'overwrite',
        data: input.data ?? {},
        version: 1,
        allowedWriters: input.allowedWriters ?? [],
        createdAt: now,
        updatedAt: now,
    };
}
//# sourceMappingURL=workspace.types.js.map