// Custom CodeMirror 6 syntax highlighting for Vadalog

import { StreamLanguage, LanguageSupport } from '@codemirror/language';

export const MODE_NAME = 'vadalog';
export const NAME = 'vadalog';
export const MIME = 'text/x-vadalog';
export const FILE_EXTENSIONS = ['vada', 'vadalog'];

// CodeMirror 6 Stream Language definition for Vadalog
const vadalogLanguage = StreamLanguage.define({
  name: MODE_NAME,
  
  startState() {
    return { inString: false };
  },

  token(stream, state) {
    // Handle strings
    if (state.inString) {
      if (stream.match(/.*?"/)) {
        state.inString = false;
        return 'string';
      }
      stream.skipToEnd();
      return 'string';
    }

    // Skip whitespace
    if (stream.eatSpace()) {
      return null;
    }

    // Comments
    if (stream.match(/^%.*$/)) {
      return 'lineComment';
    }

    // Strings
    if (stream.match(/"(?:[^\\]|\\.)*?"/)) {
      return 'string';
    }
    if (stream.match(/"/)) {
      state.inString = true;
      return 'string';
    }

    // Operators
    if (stream.match(/:-/)) {
      return 'operator';
    }
    if (stream.match(/\./)) {
      return 'operator';
    }

    // Annotations (keywords)
    if (stream.match(/@(?:input|output|bind|mapping|qbind|delete|update|post|implement|library|prob|weight|module|include|param|chase|model|schema|explain|summarize)\b/)) {
      return 'keyword';
    }

    // String operators
    if (stream.match(/(?:substring|contains|starts_with|ends_with|concat|index_of|size_of|replace|!in)\(/)) {
      return 'operator';
    }

    // Aggregators
    if (stream.match(/(?:msum|mprod|munion|mmin|mmax|mcount)\(/)) {
      return 'operator';
    }

    // Skolem functions
    if (stream.match(/#[^#\s,\(@=#]+\(/)) {
      return 'special';
    }

    // Relations (builtin)
    if (stream.match(/[^\s,\(@=#]+(?=\()/)) {
      return 'typeName';
    }

    // Numbers
    if (stream.match(/[\-]?(?:\d+(?:\.\d+)?)/)) {
      return 'number';
    }

    // Variables (uppercase)
    if (stream.match(/[A-Z$][\w$]*/)) {
      return 'variableName';
    }

    // Operators
    if (stream.match(/[-+\/*=<>!]/)) {
      return 'operator';
    }

    // Default: consume one character
    stream.next();
    return null;
  },

  languageData: {
    commentTokens: { line: '%' }
  }
});

export function getVadalogLanguage(): LanguageSupport {
  return new LanguageSupport(vadalogLanguage);
}
