"use strict";
/**
 * Core Domain Types and Abstractions for Somoni Script Compiler
 *
 * This module defines the fundamental building blocks following Domain-Driven Design
 * and Clean Architecture principles.
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CompileResult = exports.ASTNode = exports.CompilationContext = exports.CompilationOptions = exports.DiagnosticsSummary = exports.RelatedInformation = exports.Diagnostic = exports.DiagnosticLevel = exports.CompilationPipeline = exports.CompilationStep = exports.GenerationError = exports.SemanticError = exports.SyntaxError = exports.LexicalError = exports.CompilationError = exports.Result = exports.SourceRange = exports.SourceLocation = exports.ValueObject = void 0;
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable no-unused-vars */
/* eslint-disable max-params */
/* eslint-disable complexity */
// ===== VALUE OBJECTS =====
class ValueObject {
    equals(other) {
        if (other.constructor !== this.constructor) {
            return false;
        }
        const thisProps = this.getValueObjectProperties();
        const otherProps = other.getValueObjectProperties();
        if (thisProps.length !== otherProps.length) {
            return false;
        }
        return thisProps.every((prop, index) => prop === otherProps[index]);
    }
    hashCode() {
        return JSON.stringify(this.getValueObjectProperties());
    }
}
exports.ValueObject = ValueObject;
class SourceLocation extends ValueObject {
    constructor(line, column, file, length) {
        super();
        this.line = line;
        this.column = column;
        this.file = file;
        this.length = length;
        if (line < 1)
            throw new Error('Line number must be positive');
        if (column < 1)
            throw new Error('Column number must be positive');
        if (length !== undefined && length < 0)
            throw new Error('Length must be non-negative');
    }
    getValueObjectProperties() {
        return [this.line, this.column, this.file, this.length];
    }
    toString() {
        const filePrefix = this.file ? `${this.file}:` : '';
        return `${filePrefix}${this.line}:${this.column}`;
    }
    static unknown() {
        return new SourceLocation(1, 1, '<unknown>');
    }
}
exports.SourceLocation = SourceLocation;
class SourceRange extends ValueObject {
    constructor(start, end) {
        super();
        this.start = start;
        this.end = end;
        if (start.file !== end.file) {
            throw new Error('Source range cannot span multiple files');
        }
        if (start.line > end.line || (start.line === end.line && start.column > end.column)) {
            throw new Error('Start location must come before end location');
        }
    }
    getValueObjectProperties() {
        return [this.start, this.end];
    }
    contains(location) {
        if (location.file !== this.start.file)
            return false;
        if (location.line < this.start.line || location.line > this.end.line) {
            return false;
        }
        if (location.line === this.start.line && location.column < this.start.column) {
            return false;
        }
        if (location.line === this.end.line && location.column > this.end.column) {
            return false;
        }
        return true;
    }
}
exports.SourceRange = SourceRange;
// ===== RESULT PATTERN =====
class Result {
    static success(value) {
        return new Success(value);
    }
    static failure(error) {
        return new Failure(error);
    }
    static failures(errors) {
        return new Failure(errors);
    }
    map(fn) {
        return this.isSuccess() ? Result.success(fn(this.getValue())) : Result.failure(this.getError());
    }
    mapError(fn) {
        return this.isFailure() ? Result.failure(fn(this.getError())) : Result.success(this.getValue());
    }
    flatMap(fn) {
        return this.isSuccess() ? fn(this.getValue()) : Result.failure(this.getError());
    }
}
exports.Result = Result;
class Success extends Result {
    constructor(value) {
        super();
        this.value = value;
    }
    isSuccess() {
        return true;
    }
    isFailure() {
        return false;
    }
    getValue() {
        return this.value;
    }
    getError() {
        throw new Error('Cannot get error from success result');
    }
}
class Failure extends Result {
    constructor(error) {
        super();
        this.error = error;
    }
    isSuccess() {
        return false;
    }
    isFailure() {
        return true;
    }
    getValue() {
        throw new Error('Cannot get value from failure result');
    }
    getError() {
        return this.error;
    }
}
// ===== DOMAIN ERRORS =====
class CompilationError extends Error {
    constructor(message, location, code, severity = 'error') {
        super(message);
        this.location = location;
        this.code = code;
        this.severity = severity;
        this.name = this.constructor.name;
    }
    toString() {
        return `${this.severity}: ${this.message} (${this.code}) at ${this.location}`;
    }
}
exports.CompilationError = CompilationError;
class LexicalError extends CompilationError {
    constructor(message, location, character) {
        super(message, location, 'LEX001');
        this.character = character;
    }
    getErrorCategory() {
        return 'Lexical Analysis';
    }
}
exports.LexicalError = LexicalError;
class SyntaxError extends CompilationError {
    constructor(message, location, expected, actual) {
        super(message, location, 'SYN001');
        this.expected = expected;
        this.actual = actual;
    }
    getErrorCategory() {
        return 'Syntax Analysis';
    }
}
exports.SyntaxError = SyntaxError;
class SemanticError extends CompilationError {
    constructor(message, location, relatedLocation) {
        super(message, location, 'SEM001');
        this.relatedLocation = relatedLocation;
    }
    getErrorCategory() {
        return 'Semantic Analysis';
    }
}
exports.SemanticError = SemanticError;
class GenerationError extends CompilationError {
    constructor(message, location) {
        super(message, location, 'GEN001');
    }
    getErrorCategory() {
        return 'Code Generation';
    }
}
exports.GenerationError = GenerationError;
// ===== COMPILATION PIPELINE =====
class CompilationStep {
    logStep(message) {
        console.log(`[${this.name}] ${message}`);
    }
}
exports.CompilationStep = CompilationStep;
class CompilationPipeline {
    constructor(steps, reporter) {
        this.steps = steps;
        this.reporter = reporter;
    }
    async execute(input) {
        let current = input;
        const allErrors = [];
        for (const step of this.steps) {
            this.reporter.reportInfo(`Executing ${step.name}...`);
            const result = await step.execute(current);
            if (result.isFailure()) {
                const errors = result.getError();
                allErrors.push(...errors);
                errors.forEach(error => this.reporter.reportError(error));
                // Continue with next step if possible, or fail
                if (errors.some(e => e.severity === 'error')) {
                    return Result.failures(allErrors);
                }
            }
            else {
                current = result.getValue();
            }
        }
        return allErrors.length > 0 && allErrors.some(e => e.severity === 'error')
            ? Result.failures(allErrors)
            : Result.success(current);
    }
}
exports.CompilationPipeline = CompilationPipeline;
// ===== DIAGNOSTICS =====
var DiagnosticLevel;
(function (DiagnosticLevel) {
    DiagnosticLevel["Info"] = "info";
    DiagnosticLevel["Warning"] = "warning";
    DiagnosticLevel["Error"] = "error";
})(DiagnosticLevel || (exports.DiagnosticLevel = DiagnosticLevel = {}));
class Diagnostic {
    constructor(level, message, location, code, relatedInformation) {
        this.level = level;
        this.message = message;
        this.location = location;
        this.code = code;
        this.relatedInformation = relatedInformation;
    }
}
exports.Diagnostic = Diagnostic;
class RelatedInformation {
    constructor(location, message) {
        this.location = location;
        this.message = message;
    }
}
exports.RelatedInformation = RelatedInformation;
class DiagnosticsSummary {
    constructor(errorCount, warningCount, infoCount, diagnostics) {
        this.errorCount = errorCount;
        this.warningCount = warningCount;
        this.infoCount = infoCount;
        this.diagnostics = diagnostics;
    }
    get hasErrors() {
        return this.errorCount > 0;
    }
    get hasWarnings() {
        return this.warningCount > 0;
    }
    get totalCount() {
        return this.errorCount + this.warningCount + this.infoCount;
    }
}
exports.DiagnosticsSummary = DiagnosticsSummary;
// ===== COMPILATION CONTEXT =====
class CompilationOptions {
    constructor(strict = false, minify = false, sourceMap = false, target = 'es2020', outputFile, includePaths = [], defines = {}) {
        this.strict = strict;
        this.minify = minify;
        this.sourceMap = sourceMap;
        this.target = target;
        this.outputFile = outputFile;
        this.includePaths = includePaths;
        this.defines = defines;
    }
    static default() {
        return new CompilationOptions();
    }
}
exports.CompilationOptions = CompilationOptions;
class CompilationContext {
    constructor(options, diagnostics, sourceFile, workingDirectory) {
        this.options = options;
        this.diagnostics = diagnostics;
        this.sourceFile = sourceFile;
        this.workingDirectory = workingDirectory;
    }
}
exports.CompilationContext = CompilationContext;
class ASTNode {
    constructor(location) {
        this.location = location;
    }
}
exports.ASTNode = ASTNode;
// Re-export existing types for compatibility
__exportStar(require("../types"), exports);
class CompileResult {
    constructor(success, code, sourceMap, diagnostics = new DiagnosticsSummary(0, 0, 0, [])) {
        this.success = success;
        this.code = code;
        this.sourceMap = sourceMap;
        this.diagnostics = diagnostics;
    }
    static success(code, sourceMap, diagnostics) {
        return new CompileResult(true, code, sourceMap, diagnostics);
    }
    static failure(diagnostics) {
        return new CompileResult(false, undefined, undefined, diagnostics);
    }
}
exports.CompileResult = CompileResult;
//# sourceMappingURL=domain.js.map