import { ColorSpecificationSchema, FunctionSpecificationSchema, Lexer, Parser, Interpreter, Config, getAssignmentInfo, getReassignmentInfo, isNone } from './chunk-QYTZHMUN.js';
import './chunk-BNLQ6GCU.js';
import { type } from 'arktype';
import * as readlineSync from 'readline-sync';

var SchemaContentSchema = ColorSpecificationSchema.or(FunctionSpecificationSchema);
var TokenScriptSchemaResponseSchema = type({
  id: "string",
  type: "string",
  schema: "string",
  slug: "string",
  version: "string",
  content: SchemaContentSchema,
  "license_name?": "string | null"
});
async function fetchTokenScriptSchema(schemaUri, options = {}) {
  const { timeout = 1e4, headers = {}, signal } = options;
  const controller = signal ? new AbortController() : new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), timeout);
  if (signal) {
    signal.addEventListener("abort", () => controller.abort());
  }
  try {
    const response = await fetch(schemaUri, {
      signal: controller.signal,
      headers: {
        Accept: "application/json",
        "User-Agent": "TokenScript-Interpreter/1.0",
        ...headers
      }
    });
    clearTimeout(timeoutId);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status} - ${response.statusText}`);
    }
    const data = await response.json();
    const validatedData = TokenScriptSchemaResponseSchema(data);
    if (validatedData instanceof type.errors) {
      throw new Error(`Invalid schema structure: ${validatedData.summary}`);
    }
    return validatedData;
  } catch (error) {
    clearTimeout(timeoutId);
    if (error instanceof type.errors) {
      throw new Error(`Invalid schema structure: ${error.summary}`);
    }
    if (error instanceof Error) {
      if (error.name === "AbortError") {
        throw new Error(`Schema fetch timeout after ${timeout}ms`);
      }
      throw new Error(`Failed to fetch schema: ${error.message}`);
    }
    throw new Error("Unknown error occurred while fetching schema");
  }
}
async function fetchAndRegisterSchemas(schemaUris, config) {
  const configInstance = config || new Config();
  if (!schemaUris || schemaUris.length === 0) {
    return configInstance;
  }
  const schemas = await Promise.all(
    schemaUris.map(async (uri) => {
      const schemaResponse = await fetchTokenScriptSchema(uri);
      return {
        uri,
        schema: schemaResponse.content
      };
    })
  );
  return configInstance.registerSchemas(schemas);
}
async function startRepl(options = {}) {
  const { mode = "inline", schemas, references: initialReferences } = options;
  const config = await fetchAndRegisterSchemas(schemas ?? []);
  const references = { ...initialReferences };
  let scriptLines = [];
  console.log(
    `Mode: ${mode === "inline" ? "inline (execute each line)" : "script (accumulate and execute)"}`
  );
  console.log('"exit()" to exit, "clear()" to clear.');
  console.log("");
  while (true) {
    try {
      const input = readlineSync.question("> ");
      const cmd = input.toLowerCase().trim();
      if (cmd === "exit()") {
        break;
      }
      if (cmd === "clear()") {
        scriptLines = [];
        console.clear();
        console.log(
          `Mode: ${mode === "inline" ? "inline (execute each line)" : "script (accumulate and execute)"}`
        );
        console.log('"exit()" to exit, "clear()" to clear.');
        console.log("");
        continue;
      }
      if (input.trim() === "") {
        continue;
      }
      let result;
      if (mode === "inline") {
        result = interpretExpression(input, references, config, true);
      } else {
        const autoSemiLastLineInput = input.endsWith(";") ? input : `${input};`;
        scriptLines.push(autoSemiLastLineInput);
        const fullScript = scriptLines.join("\n");
        result = interpretExpression(fullScript, references, config, false);
      }
      if (result) {
        console.log(result);
      }
    } catch (error) {
      console.error(`Error: ${error.message}`);
      if (mode === "script") {
        scriptLines.pop();
      }
    }
  }
}
function getDisplayValue(ast, interpreter, result) {
  const assignmentInfo = getAssignmentInfo(ast);
  const reassignmentInfo = getReassignmentInfo(ast);
  if (assignmentInfo) {
    if (assignmentInfo.hasAssignment) {
      const varValue = interpreter.getSymbol(assignmentInfo.varName);
      if (varValue) {
        return varValue.toString();
      }
    }
    return;
  }
  if (reassignmentInfo) {
    const varValue = interpreter.getSymbol(reassignmentInfo.varName);
    if (varValue) {
      return varValue.toString();
    }
    return;
  }
  if (isNone(result)) {
    return;
  }
  if (typeof result === "string") {
    return result;
  }
  return result.toString();
}
function interpretExpression(code, references, config, isInline) {
  try {
    const lexer = new Lexer(code);
    const parser = new Parser(lexer);
    const ast = parser.parse(isInline);
    if (!ast) {
      return "No result (empty input)";
    }
    const interpreter = new Interpreter(ast, { references, config });
    const result = interpreter.interpret();
    return getDisplayValue(ast, interpreter, result);
  } catch (error) {
    throw new Error(`Interpretation failed: ${error.message}`);
  }
}

export { interpretExpression, startRepl };
//# sourceMappingURL=repl.js.map
//# sourceMappingURL=repl.js.map