"use strict";

import * as vscode from "vscode";
import { spawnSync } from "child_process";
import {
  guessFidlFormatToolPath,
  getFidlFormatToolPathFromPreferences,
  FormatToolError,
  FormatToolErrorCause,
} from "./tool_finder";

const notDefined =
  "FIDL format tool not specified. Please set the path to fidl-format in Settings.";
const notExecutable =
  "FIDL format tool doesn't exist or can't be run. Please verify the path to fidl-format in Settings.";
const formatterError = "Error formatting FIDL";

const editSettingLabel = "Edit setting";

async function showError(e: FormatToolError) {
  let message;
  let showEdit = false;
  switch (e.cause) {
    case FormatToolErrorCause.ToolNotSpecified:
      message = notDefined;
      showEdit = true;
      break;
    case FormatToolErrorCause.ToolNotExecutable:
      message = notExecutable;
      showEdit = true;
      break;
    case FormatToolErrorCause.FormatterError:
      message = `${formatterError}: ${e.formatterMessage}`;
      break;
    default:
      // This shouldn't happen. Since we don't know what kind of error we
      // have, we rethrow so this error appears in the console during
      // development.
      throw e;
  }
  let items: string[] = [];
  if (showEdit) {
    items.push(editSettingLabel);
  }
  let item = await vscode.window.showErrorMessage(message, ...items);
  switch (item) {
    case undefined:
    case null:
      // The user did not choose to edit setting.
      return;
    case editSettingLabel:
      vscode.commands.executeCommand(
        "workbench.action.openSettings",
        "fidl.tools.formatter"
      );
  }
}

/**
 * A formatting edit provider that runs fidl-format over the code in the
 * current FIDL file.
 *
 * Objects of this class will check for the presence of the fidl-format path in
 * settings when instantiated and on every formatting request. If the path is
 * left empty (the default) and the path to fidl-format isn't specified,
 * objects of this class will show a notification to the user each time they
 * try to format a FIDL file.
 */
export default class FidlFormattingEditProvider
  implements vscode.DocumentFormattingEditProvider {
  /**
   * The cached path to the autodetected fidl-format tool. This is set once
   * for the session if the user hasn't explicitly set a path in preferences.
   */
  cachedGuessedFidlFormatToolPath: string | null = null;
  constructor() {
    if (getFidlFormatToolPathFromPreferences()) {
      // The fidl-format tool path is specified in preferences, so no
      // caching is needed.
      return;
    }

    guessFidlFormatToolPath().then(
      (p) => (this.cachedGuessedFidlFormatToolPath = p),
      (e: FormatToolError) => showError(e)
    );
  }

  async provideDocumentFormattingEdits(
    document: vscode.TextDocument
  ): Promise<vscode.TextEdit[]> {
    const fromPrefs = getFidlFormatToolPathFromPreferences();
    let formatTool: string;

    if (fromPrefs) {
      // If the user has set a fidl-format path, that takes precedence.
      formatTool = fromPrefs;
      // Remove any cached (i.e. autodetected) tool.
      this.cachedGuessedFidlFormatToolPath = null;
    } else if (this.cachedGuessedFidlFormatToolPath) {
      // If there is a cached fidl-format path, use that for this
      // session.
      formatTool = this.cachedGuessedFidlFormatToolPath;
    } else {
      // Find the fidl-format tool.
      try {
        formatTool = await guessFidlFormatToolPath();
      } catch (e) {
        showError(e);
        return [];
      }
    }

    // FIDL files are assumed to always be UTF-8.
    const format = spawnSync(formatTool, [], {
      encoding: "utf8",
      input: document.getText(),
    });
    if (format.status) {
      // fidl-format exited with an error.
      const e = new FormatToolError(FormatToolErrorCause.FormatterError);
      e.formatterMessage = format.stderr;
      showError(e);
      // Return no edits. i.e. no changes to document.
      return [];
    }

    const fileStart = new vscode.Position(0, 0);
    const fileEnd = document.lineAt(document.lineCount - 1).range.end;

    // Casting: because spawnSync was called with an encoding,
    // format.stdout is already a string.
    return [
      new vscode.TextEdit(
        new vscode.Range(fileStart, fileEnd),
        format.stdout as string
      ),
    ];
  }
}
