import * as ace from './ace';
import {DEFAULT_INPUT, getAceMode, InputMode, Mode, OutputMode} from './mode';
import {entries, values, wordWrap} from './util';

// Ace editor options that only apply to the output editor.
const OUTPUT_EDITOR_OPTIONS: ace.Options = {
  readOnly: true,
  // These highlights are just distracting and usually stay on the first line.
  highlightActiveLine: false,
  highlightGutterLine: false,
  // For guides to be useful, we would have to infer the indentation size.
  displayIndentGuides: false,
};

// Ace session options that only apply to output sessions that contain errors.
const ERROR_SESSION_OPTIONS: ace.Options = {
  // Error messages are often printed on one long line.
  wrap: true,
};

// Number of characters to wrap text at for annotation tooltips.
const ANNOTATION_TEXT_WRAP = 66;

// The main data structure used by the Editors class.
type SessionMap = Record<InputMode, InputRecord>;

// A map from input modes to serialized input sessions. The key type is string
// rather than InputMode because the set of input modes might have changed since
// the user last had the session map saved to local storage.
type SavedSessionMap = {
  [inputMode: string]: ace.SavedSession;
};

interface InputRecord {
  session: ace.Session;
  // Partial because the output records are set as needed, not up front.
  outputs: Partial<Record<OutputMode, OutputRecord>>;
}

interface OutputRecord {
  session: ace.Session;
  options: Options;
  inputAnnotations: ace.Annotation[];
}

// Options sent to the server. This corresonds to the Options type in server.go.
export type Options = {
  [key: string]: any;
};

// An annotation received from the server. This corresponds to the Annotation
// type in server.go, and is different from the ace.Annotation type.
export interface Annotation {
  line: number; // one-based
  column: number; // one-based
  kind: 'info' | 'warning' | 'error';
  text: string;
}

// Editors manages state for the input and output Ace editors.
export class Editors {
  readonly inputEditor: ace.Editor;
  readonly outputEditor: ace.Editor;
  readonly editorOptions: ace.Options;
  readonly sessionOptions: ace.Options;
  readonly sessions: SessionMap;

  constructor(sessions: SessionMap) {
    // These HTML IDs are set in elm/Editors.elm.
    this.inputEditor = Editors.newEditor('InputEditor');
    this.outputEditor = Editors.newEditor('OutputEditor');
    this.outputEditor.setOptions(OUTPUT_EDITOR_OPTIONS);
    this.editorOptions = {};
    this.sessionOptions = {};
    this.sessions = sessions;
  }

  static newEditor(htmlID: string): ace.Editor {
    const editor = ace.edit(htmlID);
    // We have our own settings menu in the app.
    editor.commands.removeCommand('showSettingsMenu');
    // We use Ctrl-[ and Ctrl-] in Editors.elm to navigate editor tabs.
    editor.commands.removeCommand('blockindent');
    editor.commands.removeCommand('blockoutdent');
    // Ctrl/Cmd-L interferes with the browser's address bar shortcut.
    const gotoline = editor.commands.byName.gotoline;
    gotoline.bindKey = {win: 'Ctrl-G', mac: 'Ctrl-G'};
    editor.commands.addCommand(gotoline);
    // editor.commands.bindKey(ctrlG, gotoline);
    // For accessiblity, allow users to "escape" the editor with a keyboard
    // shortcut that makes Tab and Shift+Tab regain their normal behavior.
    // https://www.w3.org/TR/2009/WD-wai-aria-practices-20090224/#richtext
    const indentCommand = editor.commands.byName.indent;
    const outdentCommand = editor.commands.byName.outdent;
    const setTabMode = (indent: boolean): void => {
      if (indent) {
        editor.commands.addCommand(indentCommand);
        editor.commands.addCommand(outdentCommand);
      } else {
        editor.commands.removeCommand('indent');
        editor.commands.removeCommand('outdent');
      }
    };
    let currentTabMode = false;
    setTabMode(currentTabMode);
    editor.on('focus', () => {
      setTabMode((currentTabMode = true));
    });
    editor.commands.addCommand({
      name: 'toggleTabMode',
      bindKey: {win: 'Ctrl-M', mac: 'Ctrl-M'},
      exec: () => {
        setTabMode((currentTabMode = !currentTabMode));
      },
    });
    return editor;
  }

  newSession(mode: Mode): ace.Session {
    const session = ace.createEditSession('', getAceMode(mode));
    session.setOptions(this.sessionOptions);
    return session;
  }

  toJSON(): SavedSessionMap {
    const json: SavedSessionMap = {};
    for (const [inputMode, {session}] of entries(this.sessions)) {
      json[inputMode] = ace.sessionToJSON(session);
    }
    return json;
  }

  static fromJSON(json?: SavedSessionMap): Editors {
    const sessions: Partial<SessionMap> = {};
    for (const [inputMode, defaultValue] of entries(DEFAULT_INPUT)) {
      const savedSession = json?.[inputMode];
      // Load the saved session only if it is present and nonempty.
      if (savedSession?.value) {
        const session = ace.sessionFromJSON(
          savedSession,
          getAceMode(inputMode)
        );
        sessions[inputMode] = {session, outputs: {}};
      } else {
        const session = ace.createEditSession(
          defaultValue,
          getAceMode(inputMode)
        );
        sessions[inputMode] = {session, outputs: {}};
      }
    }
    return new Editors(sessions as SessionMap);
  }

  editorsDo(editorFn: (e: ace.Editor) => void) {
    editorFn(this.inputEditor);
    editorFn(this.outputEditor);
  }

  sessionsDo(sessionFn: (s: ace.Session) => void) {
    for (const {session, outputs} of values(this.sessions)) {
      sessionFn(session);
      for (const {session} of values(outputs)) {
        sessionFn(session);
      }
    }
  }

  showSessions(inputMode: InputMode, outputMode: OutputMode) {
    const inputRecord = this.sessions[inputMode];
    const outputRecord =
      inputRecord.outputs[outputMode] ??
      (inputRecord.outputs[outputMode] = {
        session: this.newSession(outputMode),
        options: {},
        inputAnnotations: [],
      });
    inputRecord.session.setAnnotations(outputRecord.inputAnnotations);
    this.inputEditor.setSession(inputRecord.session);
    this.outputEditor.setSession(outputRecord.session);
  }

  setOutput(
    inputMode: InputMode,
    outputMode: OutputMode,
    content: string,
    annotations: Annotation[],
    errorTitle?: string
  ) {
    const inputRecord = this.sessions[inputMode];
    const outputRecord = inputRecord.outputs[outputMode];
    if (outputRecord == undefined) {
      return;
    }
    const session = outputRecord.session;
    if (errorTitle == undefined) {
      session.setMode(getAceMode(outputMode));
      session.setOptions(this.sessionOptions);
      session.setValue(content);
      session.fidlboltErrorSession = false;
    } else {
      session.setMode('ace/mode/error');
      session.setOptions(ERROR_SESSION_OPTIONS);
      session.setValue(errorTitle + ':\n\n' + content);
      session.fidlboltErrorSession = true;
    }
    outputRecord.inputAnnotations = annotations.map(
      ({line, column, kind, text}) => ({
        // Convert one-based to zero-based.
        row: line - 1,
        column: column - 1,
        type: kind,
        text: wordWrap(text, ANNOTATION_TEXT_WRAP),
      })
    );
    inputRecord.session.setAnnotations(outputRecord.inputAnnotations);
  }

  applySettings(settings: ace.Options) {
    this.editorOptions.theme = 'ace/theme/' + settings.theme;
    this.editorOptions.showPrintMargin =
      (settings.printMarginColumn as number) > 0;
    this.editorOptions.highlightGutterLine = settings.highlightActiveLine;
    this.editorOptions.fontSize =
      Math.max(1, settings.fontSize as number) + 'px';
    this.sessionOptions.tabSize = Math.max(1, settings.tabSize as number);
    this.sessionOptions.navigateWithinSoftTabs = !settings.atomicSoftTabs;
    if (settings.keyboardHandler === 'ace') {
      this.editorOptions.keyboardHandler = null;
    } else {
      this.editorOptions.keyboardHandler =
        'ace/keyboard/' + settings.keyboardHandler;
    }
    for (const field of [
      'displayIndentGuides',
      'foldStyle',
      'highlightActiveLine',
      'printMarginColumn',
      'relativeLineNumbers',
      'scrollPastEnd',
      'showGutter',
      'showInvisibles',
      'showLineNumbers',
      'showPrintMargin',
    ]) {
      this.editorOptions[field] = settings[field];
    }
    for (const field of ['indentedSoftWrap', 'useSoftTabs', 'wrap']) {
      this.sessionOptions[field] = settings[field];
    }

    this.inputEditor.setOptions(this.editorOptions);
    this.outputEditor.setOptions({
      ...this.editorOptions,
      ...OUTPUT_EDITOR_OPTIONS,
    });
    this.sessionsDo(session => {
      session.setOptions(this.sessionOptions);
      if (session.fidlboltErrorSession) {
        session.setOptions(ERROR_SESSION_OPTIONS);
      }
    });
  }

  resize() {
    this.editorsDo(e => e.resize());
  }
}
