"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const labels = require("../../../../base/common/labels.js");
const path = require("../../../../base/common/path.js");
const resources = require("../../../../base/common/resources.js");
const strings = require("../../../../base/common/strings.js");
const uuid = require("../../../../base/common/uuid.js");
const languageConfigurationRegistry = require("../../../common/languages/languageConfigurationRegistry.js");
const snippetParser = require("./snippetParser.js");
const nls = require("../../../../nls.js");
const workspace = require("../../../../platform/workspace/common/workspace.js");
class CompositeSnippetVariableResolver {
  constructor(_delegates) {
    this._delegates = _delegates;
  }
  resolve(variable) {
    for (const delegate of this._delegates) {
      let value = delegate.resolve(variable);
      if (value !== void 0) {
        return value;
      }
    }
    return void 0;
  }
}
class SelectionBasedVariableResolver {
  constructor(_model, _selection, _selectionIdx, _overtypingCapturer) {
    this._model = _model;
    this._selection = _selection;
    this._selectionIdx = _selectionIdx;
    this._overtypingCapturer = _overtypingCapturer;
  }
  resolve(variable) {
    const { name } = variable;
    if (name === "SELECTION" || name === "TM_SELECTED_TEXT") {
      let value = this._model.getValueInRange(this._selection) || void 0;
      let isMultiline = this._selection.startLineNumber !== this._selection.endLineNumber;
      if (!value && this._overtypingCapturer) {
        const info = this._overtypingCapturer.getLastOvertypedInfo(this._selectionIdx);
        if (info) {
          value = info.value;
          isMultiline = info.multiline;
        }
      }
      if (value && isMultiline && variable.snippet) {
        const line = this._model.getLineContent(this._selection.startLineNumber);
        const lineLeadingWhitespace = strings.getLeadingWhitespace(line, 0, this._selection.startColumn - 1);
        let varLeadingWhitespace = lineLeadingWhitespace;
        variable.snippet.walk((marker) => {
          if (marker === variable) {
            return false;
          }
          if (marker instanceof snippetParser.Text) {
            varLeadingWhitespace = strings.getLeadingWhitespace(strings.splitLines(marker.value).pop());
          }
          return true;
        });
        const whitespaceCommonLength = strings.commonPrefixLength(varLeadingWhitespace, lineLeadingWhitespace);
        value = value.replace(/(\r\n|\r|\n)(.*)/g, (m, newline, rest) => `${newline}${varLeadingWhitespace.substr(whitespaceCommonLength)}${rest}`);
      }
      return value;
    } else if (name === "TM_CURRENT_LINE") {
      return this._model.getLineContent(this._selection.positionLineNumber);
    } else if (name === "TM_CURRENT_WORD") {
      const info = this._model.getWordAtPosition({
        lineNumber: this._selection.positionLineNumber,
        column: this._selection.positionColumn
      });
      return info && info.word || void 0;
    } else if (name === "TM_LINE_INDEX") {
      return String(this._selection.positionLineNumber - 1);
    } else if (name === "TM_LINE_NUMBER") {
      return String(this._selection.positionLineNumber);
    }
    return void 0;
  }
}
class ModelBasedVariableResolver {
  constructor(_labelService, _model) {
    this._labelService = _labelService;
    this._model = _model;
  }
  resolve(variable) {
    const { name } = variable;
    if (name === "TM_FILENAME") {
      return path.basename(this._model.uri.fsPath);
    } else if (name === "TM_FILENAME_BASE") {
      const name2 = path.basename(this._model.uri.fsPath);
      const idx = name2.lastIndexOf(".");
      if (idx <= 0) {
        return name2;
      } else {
        return name2.slice(0, idx);
      }
    } else if (name === "TM_DIRECTORY") {
      if (path.dirname(this._model.uri.fsPath) === ".") {
        return "";
      }
      return this._labelService.getUriLabel(resources.dirname(this._model.uri));
    } else if (name === "TM_FILEPATH") {
      return this._labelService.getUriLabel(this._model.uri);
    } else if (name === "RELATIVE_FILEPATH") {
      return this._labelService.getUriLabel(this._model.uri, { relative: true, noPrefix: true });
    }
    return void 0;
  }
}
class ClipboardBasedVariableResolver {
  constructor(_readClipboardText, _selectionIdx, _selectionCount, _spread) {
    this._readClipboardText = _readClipboardText;
    this._selectionIdx = _selectionIdx;
    this._selectionCount = _selectionCount;
    this._spread = _spread;
  }
  resolve(variable) {
    if (variable.name !== "CLIPBOARD") {
      return void 0;
    }
    const clipboardText = this._readClipboardText();
    if (!clipboardText) {
      return void 0;
    }
    if (this._spread) {
      const lines = clipboardText.split(/\r\n|\n|\r/).filter((s) => !strings.isFalsyOrWhitespace(s));
      if (lines.length === this._selectionCount) {
        return lines[this._selectionIdx];
      }
    }
    return clipboardText;
  }
}
class CommentBasedVariableResolver {
  constructor(_model, _selection) {
    this._model = _model;
    this._selection = _selection;
  }
  resolve(variable) {
    const { name } = variable;
    const langId = this._model.getLanguageIdAtPosition(this._selection.selectionStartLineNumber, this._selection.selectionStartColumn);
    const config = languageConfigurationRegistry.LanguageConfigurationRegistry.getComments(langId);
    if (!config) {
      return void 0;
    }
    if (name === "LINE_COMMENT") {
      return config.lineCommentToken || void 0;
    } else if (name === "BLOCK_COMMENT_START") {
      return config.blockCommentStartToken || void 0;
    } else if (name === "BLOCK_COMMENT_END") {
      return config.blockCommentEndToken || void 0;
    }
    return void 0;
  }
}
class TimeBasedVariableResolver {
  constructor() {
    this._date = /* @__PURE__ */ new Date();
  }
  resolve(variable) {
    const { name } = variable;
    if (name === "CURRENT_YEAR") {
      return String(this._date.getFullYear());
    } else if (name === "CURRENT_YEAR_SHORT") {
      return String(this._date.getFullYear()).slice(-2);
    } else if (name === "CURRENT_MONTH") {
      return String(this._date.getMonth().valueOf() + 1).padStart(2, "0");
    } else if (name === "CURRENT_DATE") {
      return String(this._date.getDate().valueOf()).padStart(2, "0");
    } else if (name === "CURRENT_HOUR") {
      return String(this._date.getHours().valueOf()).padStart(2, "0");
    } else if (name === "CURRENT_MINUTE") {
      return String(this._date.getMinutes().valueOf()).padStart(2, "0");
    } else if (name === "CURRENT_SECOND") {
      return String(this._date.getSeconds().valueOf()).padStart(2, "0");
    } else if (name === "CURRENT_DAY_NAME") {
      return TimeBasedVariableResolver.dayNames[this._date.getDay()];
    } else if (name === "CURRENT_DAY_NAME_SHORT") {
      return TimeBasedVariableResolver.dayNamesShort[this._date.getDay()];
    } else if (name === "CURRENT_MONTH_NAME") {
      return TimeBasedVariableResolver.monthNames[this._date.getMonth()];
    } else if (name === "CURRENT_MONTH_NAME_SHORT") {
      return TimeBasedVariableResolver.monthNamesShort[this._date.getMonth()];
    } else if (name === "CURRENT_SECONDS_UNIX") {
      return String(Math.floor(this._date.getTime() / 1e3));
    }
    return void 0;
  }
}
TimeBasedVariableResolver.dayNames = [nls.localize("Sunday", "Sunday"), nls.localize("Monday", "Monday"), nls.localize("Tuesday", "Tuesday"), nls.localize("Wednesday", "Wednesday"), nls.localize("Thursday", "Thursday"), nls.localize("Friday", "Friday"), nls.localize("Saturday", "Saturday")];
TimeBasedVariableResolver.dayNamesShort = [nls.localize("SundayShort", "Sun"), nls.localize("MondayShort", "Mon"), nls.localize("TuesdayShort", "Tue"), nls.localize("WednesdayShort", "Wed"), nls.localize("ThursdayShort", "Thu"), nls.localize("FridayShort", "Fri"), nls.localize("SaturdayShort", "Sat")];
TimeBasedVariableResolver.monthNames = [nls.localize("January", "January"), nls.localize("February", "February"), nls.localize("March", "March"), nls.localize("April", "April"), nls.localize("May", "May"), nls.localize("June", "June"), nls.localize("July", "July"), nls.localize("August", "August"), nls.localize("September", "September"), nls.localize("October", "October"), nls.localize("November", "November"), nls.localize("December", "December")];
TimeBasedVariableResolver.monthNamesShort = [nls.localize("JanuaryShort", "Jan"), nls.localize("FebruaryShort", "Feb"), nls.localize("MarchShort", "Mar"), nls.localize("AprilShort", "Apr"), nls.localize("MayShort", "May"), nls.localize("JuneShort", "Jun"), nls.localize("JulyShort", "Jul"), nls.localize("AugustShort", "Aug"), nls.localize("SeptemberShort", "Sep"), nls.localize("OctoberShort", "Oct"), nls.localize("NovemberShort", "Nov"), nls.localize("DecemberShort", "Dec")];
class WorkspaceBasedVariableResolver {
  constructor(_workspaceService) {
    this._workspaceService = _workspaceService;
  }
  resolve(variable) {
    if (!this._workspaceService) {
      return void 0;
    }
    const workspaceIdentifier = workspace.toWorkspaceIdentifier(this._workspaceService.getWorkspace());
    if (!workspaceIdentifier) {
      return void 0;
    }
    if (variable.name === "WORKSPACE_NAME") {
      return this._resolveWorkspaceName(workspaceIdentifier);
    } else if (variable.name === "WORKSPACE_FOLDER") {
      return this._resoveWorkspacePath(workspaceIdentifier);
    }
    return void 0;
  }
  _resolveWorkspaceName(workspaceIdentifier) {
    if (workspace.isSingleFolderWorkspaceIdentifier(workspaceIdentifier)) {
      return path.basename(workspaceIdentifier.uri.path);
    }
    let filename = path.basename(workspaceIdentifier.configPath.path);
    if (filename.endsWith(workspace.WORKSPACE_EXTENSION)) {
      filename = filename.substr(0, filename.length - workspace.WORKSPACE_EXTENSION.length - 1);
    }
    return filename;
  }
  _resoveWorkspacePath(workspaceIdentifier) {
    if (workspace.isSingleFolderWorkspaceIdentifier(workspaceIdentifier)) {
      return labels.normalizeDriveLetter(workspaceIdentifier.uri.fsPath);
    }
    let filename = path.basename(workspaceIdentifier.configPath.path);
    let folderpath = workspaceIdentifier.configPath.fsPath;
    if (folderpath.endsWith(filename)) {
      folderpath = folderpath.substr(0, folderpath.length - filename.length - 1);
    }
    return folderpath ? labels.normalizeDriveLetter(folderpath) : "/";
  }
}
class RandomBasedVariableResolver {
  resolve(variable) {
    const { name } = variable;
    if (name === "RANDOM") {
      return Math.random().toString().slice(-6);
    } else if (name === "RANDOM_HEX") {
      return Math.random().toString(16).slice(-6);
    } else if (name === "UUID") {
      return uuid.generateUuid();
    }
    return void 0;
  }
}
exports.ClipboardBasedVariableResolver = ClipboardBasedVariableResolver;
exports.CommentBasedVariableResolver = CommentBasedVariableResolver;
exports.CompositeSnippetVariableResolver = CompositeSnippetVariableResolver;
exports.ModelBasedVariableResolver = ModelBasedVariableResolver;
exports.RandomBasedVariableResolver = RandomBasedVariableResolver;
exports.SelectionBasedVariableResolver = SelectionBasedVariableResolver;
exports.TimeBasedVariableResolver = TimeBasedVariableResolver;
exports.WorkspaceBasedVariableResolver = WorkspaceBasedVariableResolver;
