var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
  return value;
};
import { U as Uri, P as Position, R as Range, w as window, D as DiagnosticSeverity, a as workspace, u as updateRangeMultipleChanges, c as commands, t as telemetryRecorder, e as executeEdit, p as ps, T as TERMINAL_EDIT_STATES, d as dedent, b as ThemeColor, l as languages, C as CodeLens, s as setTutorialUri, f as logSidebarClick, g as Disposable } from "./agent.worker-6-HoPAWv.js";
const EMOJI_SVG_TEMPLATE = `<svg width="32" height="32" xmlns="http://www.w3.org/2000/svg">
    <text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="24px">{emoji}</text>
</svg>`;
const transformEmojiToSvg = (emoji) => {
  const svg = EMOJI_SVG_TEMPLATE.replace("{emoji}", emoji);
  const uri = "data:image/svg+xml;base64," + Buffer.from(svg).toString("base64");
  return Uri.parse(uri);
};
function findRangeOfText(document, searchText) {
  for (let line = 0; line < document.lineCount; line++) {
    const lineText = document.lineAt(line);
    const indexOfText = lineText.text.indexOf(searchText);
    if (indexOfText >= 0) {
      const start = new Position(line, indexOfText);
      const end = new Position(line, indexOfText + searchText.length);
      return new Range(start, end);
    }
  }
  return null;
}
const TUTORIAL_EMOJIS = {
  Todo: "&#128073;"
  // 👉
};
const TODO_DECORATION = window.createTextEditorDecorationType({
  gutterIconPath: transformEmojiToSvg(TUTORIAL_EMOJIS.Todo),
  gutterIconSize: "contain"
});
const setFixDiagnostic = (collection, uri, range) => {
  if (!collection || collection.has(uri)) {
    return;
  }
  collection.set(uri, [
    {
      range,
      message: "Python: Implicit string concatenation not allowed",
      severity: DiagnosticSeverity.Error
    }
  ]);
};
const registerEditTutorialCommand = (editor, onComplete, range) => {
  let trackedRange = range;
  const rangeTracker = workspace.onDidChangeTextDocument((event) => {
    if (event.document !== editor.document) {
      return;
    }
    const changes = new Array(...event.contentChanges);
    const updatedRange = updateRangeMultipleChanges(trackedRange, changes);
    if (!updatedRange.isEqual(trackedRange)) {
      trackedRange = updatedRange;
    }
  });
  const editCommand = commands.registerCommand(
    "cody.tutorial.edit",
    async (_document, source = "editor") => {
      telemetryRecorder.recordEvent("cody.interactiveTutorial", "edit", {
        privateMetadata: { source }
      });
      editor.setDecorations(TODO_DECORATION, []);
      const task = await executeEdit({
        configuration: {
          document: editor.document,
          range: trackedRange,
          preInstruction: ps`Function that finds logs in a dir`
        }
      });
      if (!task) {
        return;
      }
      const interval = setInterval(async () => {
        if (TERMINAL_EDIT_STATES.includes(task.state)) {
          clearInterval(interval);
          onComplete();
        }
      }, 100);
    }
  );
  return [rangeTracker, editCommand];
};
const registerChatTutorialCommand = (onComplete) => {
  const disposable = commands.registerCommand(
    "cody.tutorial.chat",
    async (_document, source = "editor") => {
      telemetryRecorder.recordEvent("cody.interactiveTutorial", "chat", {
        privateMetadata: { source }
      });
      await commands.executeCommand("cody.chat.newEditorPanel");
      onComplete();
    }
  );
  return disposable;
};
const registerAutocompleteListener = (editor, activeStep) => {
  const disposable = window.onDidChangeTextEditorSelection(async ({ textEditor }) => {
    const document = textEditor.document;
    if (document.uri !== editor.document.uri) {
      return;
    }
    if (!textEditor.selection.isEmpty) {
      return;
    }
    if (!activeStep || activeStep.type !== "onTextChange") {
      return;
    }
    if (activeStep.range.contains(textEditor.selection.active) && document.getText(activeStep.range).trim() === activeStep.originalText) {
      await commands.executeCommand("cody.autocomplete.manual-trigger");
    }
  });
  return disposable;
};
var define_process_default = { env: {} };
const getStepContent = (step) => {
  let stepContent = "";
  switch (step) {
    case "autocomplete":
      stepContent = dedent`
                ### Welcome to Cody!
                """
                Learn how to use Cody to write, edit and fix code by completing the 4 tasks below.
                """

                ### Task 1 of 4: Autocomplete
                """
                Place your cursor at the end of the following function and press tab to accept the Cody-powered autocomplete.
                """
                def greet(name, surname):
                    """Greets a user with a simple message"""
                    
                #    ^ Autocomplete: Place cursor above
                # When you see a suggestion, press Tab to accept or Opt+\ to generate another.
            `;
      break;
    case "edit":
      stepContent = dedent`
                \n\n
                ### Task 2 of 4: Edit Code with instructions
                """
                Place the cursor on the empty line below, and press Opt+K to open the Edit Code input.
                We've pre-filled the instruction, all you need to do is choose Submit.
                """

                # ^ Start an Edit (Opt+K)
            `;
      break;
    case "fix":
      stepContent = dedent`
                \n\n
                ### Task 3 of 4: Ask Cody to Fix
                """
                The following code has a bug. Hover over the text with the error,
                select "Quick Fix" and then "Ask Cody to Fix".
                """
                def log_fruits():
                    print("List of fruits:", "apple,", "banana,", "cherry")
                #         ^ Fix: Place cursor anywhere here, press Cmd+., and "Ask Cody to Fix"
            `;
      break;
    case "chat":
      stepContent = dedent`
                \n\n
                ### Task 4 of 4: Start a chat
                #
                # Start a Chat (Opt+L)
            `;
  }
  return define_process_default.platform === "darwin" ? stepContent : stepContent.replace("Opt", "Alt").replace("Cmd", "Ctrl");
};
const getStepData = (document, step) => {
  switch (step) {
    case "autocomplete": {
      const triggerText = findRangeOfText(document, "^ Autocomplete:");
      if (!triggerText) {
        return null;
      }
      const autocompleteRange = new Range(
        new Position(triggerText.start.line - 1, 0),
        new Position(triggerText.start.line - 1, Number.MAX_SAFE_INTEGER)
      );
      return {
        key: "autocomplete",
        range: autocompleteRange,
        originalText: document.getText(autocompleteRange).trim(),
        type: "onTextChange"
      };
    }
    case "edit": {
      const triggerText = findRangeOfText(document, "Start an Edit");
      if (!triggerText) {
        return null;
      }
      const editLine = triggerText.start.line - 1;
      return {
        key: "edit",
        range: new Range(
          new Position(editLine, 0),
          new Position(editLine, Number.MAX_SAFE_INTEGER)
        ),
        type: "manual"
      };
    }
    case "fix": {
      const triggerText = findRangeOfText(document, "^ Fix:");
      if (!triggerText) {
        return null;
      }
      const fixLine = triggerText.start.line - 1;
      const fixRange = new Range(
        new Position(fixLine, document.lineAt(fixLine).firstNonWhitespaceCharacterIndex),
        new Position(fixLine, Number.MAX_SAFE_INTEGER)
      );
      return {
        key: "fix",
        range: fixRange,
        originalText: document.getText(fixRange).trim(),
        type: "onTextChange"
      };
    }
    case "chat": {
      const triggerText = findRangeOfText(document, "Start a Chat");
      if (!triggerText) {
        return null;
      }
      const chatLine = triggerText.start.line;
      return {
        key: "chat",
        range: new Range(
          new Position(chatLine, 0),
          new Position(chatLine, Number.MAX_SAFE_INTEGER)
        ),
        type: "manual"
      };
    }
  }
};
const getNextStep = (step) => {
  switch (step) {
    case "autocomplete":
      return "edit";
    case "edit":
      return "fix";
    case "fix":
      return "chat";
    case "chat":
      return null;
  }
};
const initTutorialDocument = async (uri) => {
  const firstStep = getStepContent("autocomplete");
  await workspace.fs.writeFile(uri, Buffer.from(firstStep));
  return workspace.openTextDocument(uri);
};
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const resetDocument = async (uri) => {
  await commands.executeCommand("workbench.action.closeActiveEditor", uri);
  await sleep(250);
  return initTutorialDocument(uri);
};
class TutorialLinkProvider {
  constructor(editor) {
    this.editor = editor;
  }
  provideDocumentLinks(document, token) {
    if (document.uri.fsPath !== this.editor.document.uri.fsPath) {
      return [];
    }
    const links = [];
    const editRange = findRangeOfText(document, "Start an Edit");
    if (editRange) {
      const params = [document, "link"];
      links.push(
        new (void 0)(
          editRange,
          Uri.parse(
            `command:cody.tutorial.edit?${encodeURIComponent(JSON.stringify(params))}`
          )
        )
      );
    }
    const chatRange = findRangeOfText(document, "Start a Chat");
    if (chatRange) {
      const params = [document, "link"];
      links.push(
        new (void 0)(
          chatRange,
          Uri.parse(
            `command:cody.tutorial.chat?${encodeURIComponent(JSON.stringify(params))}`
          )
        )
      );
    }
    const linkDecoration = window.createTextEditorDecorationType({
      color: new ThemeColor("textLink.activeForeground")
    });
    this.editor.setDecorations(linkDecoration, links);
    return links;
  }
}
class ResetLensProvider {
  constructor(editor) {
    __publicField(this, "disposables", []);
    this.editor = editor;
    this.disposables.push(languages.registerCodeLensProvider(editor.document.uri, this));
  }
  provideCodeLenses(document) {
    return [
      new CodeLens(new Range(0, 0, 0, 0), {
        title: "Reset Tutorial",
        command: "cody.tutorial.reset"
      })
    ];
  }
  dispose() {
    for (const disposable of this.disposables) {
      disposable.dispose();
    }
    this.disposables = [];
  }
}
const startTutorial = async (document) => {
  const disposables = [];
  const editor = await window.showTextDocument(document);
  const diagnosticCollection = languages.createDiagnosticCollection("codyTutorial");
  disposables.push(diagnosticCollection);
  telemetryRecorder.recordEvent("cody.interactiveTutorial", "started");
  let activeStep = null;
  let activeRangeListener;
  let successListener;
  const setActiveRangeListener = (range) => {
    activeRangeListener == null ? void 0 : activeRangeListener.dispose();
    activeRangeListener = workspace.onDidChangeTextDocument((event) => {
      if (event.document.uri !== editor.document.uri) {
        return;
      }
      if (!activeStep) {
        return;
      }
      const changes = new Array(...event.contentChanges);
      const newInteractiveRange = updateRangeMultipleChanges(range, changes);
      if (!newInteractiveRange.isEqual(range)) {
        activeStep.range = newInteractiveRange;
      }
    });
    return activeRangeListener;
  };
  const progressToNextStep = async () => {
    const nextStep = (activeStep == null ? void 0 : activeStep.key) ? getNextStep(activeStep.key) : "autocomplete";
    if (activeStep == null ? void 0 : activeStep.key) {
      telemetryRecorder.recordEvent("cody.interactiveTutorial.stepComplete", activeStep.key);
    }
    if (nextStep === null) {
      editor.setDecorations(TODO_DECORATION, []);
      telemetryRecorder.recordEvent("cody.interactiveTutorial", "finished");
      return;
    }
    switch (activeStep == null ? void 0 : activeStep.key) {
      case "autocomplete":
        break;
      case "fix":
        diagnosticCollection == null ? void 0 : diagnosticCollection.clear();
        break;
    }
    activeRangeListener == null ? void 0 : activeRangeListener.dispose();
    editor.setDecorations(TODO_DECORATION, []);
    const needsInsertion = nextStep !== "autocomplete";
    if (needsInsertion) {
      const content = getStepContent(nextStep);
      await editor.edit((editBuilder) => {
        editBuilder.insert(new Position(editor.document.lineCount, 0), content);
      });
    }
    editor.document.save();
    activeStep = getStepData(editor.document, nextStep);
    if (!activeStep) {
      return;
    }
    disposables.push(startListeningForSuccess(nextStep), setActiveRangeListener(activeStep.range));
    editor.setDecorations(TODO_DECORATION, [activeStep.range]);
    switch (nextStep) {
      case "autocomplete":
        disposables.push(registerAutocompleteListener(editor, activeStep));
        break;
      case "fix":
        setFixDiagnostic(diagnosticCollection, editor.document.uri, activeStep.range);
        break;
      case "edit":
        disposables.push(
          ...registerEditTutorialCommand(editor, progressToNextStep, activeStep.range)
        );
        break;
      case "chat":
        disposables.push(registerChatTutorialCommand(progressToNextStep));
        break;
    }
  };
  const startListeningForSuccess = (key) => {
    successListener == null ? void 0 : successListener.dispose();
    successListener = workspace.onDidChangeTextDocument(async ({ document: document2 }) => {
      if (document2.uri !== editor.document.uri) {
        return;
      }
      if ((activeStep == null ? void 0 : activeStep.key) !== key || activeStep.type !== "onTextChange") {
        return;
      }
      const activeText = editor.document.getText(activeStep.range).trim();
      if (activeText.length > 0 && activeText !== activeStep.originalText) {
        if (key === "fix") {
          diagnosticCollection.clear();
        }
        successListener == null ? void 0 : successListener.dispose();
        progressToNextStep();
      }
    });
    return successListener;
  };
  progressToNextStep();
  disposables.push(
    startListeningForSuccess("autocomplete"),
    new ResetLensProvider(editor),
    languages.registerDocumentLinkProvider(
      editor.document.uri,
      new TutorialLinkProvider(editor)
    ),
    window.onDidChangeVisibleTextEditors((editors) => {
      const tutorialIsActive = editors.find(
        (editor2) => editor2.document.uri.toString() === document.uri.toString()
      );
      if (!tutorialIsActive || !(activeStep == null ? void 0 : activeStep.range)) {
        return;
      }
      editor.setDecorations(TODO_DECORATION, [activeStep.range]);
    })
  );
  return new Disposable(() => {
    for (const disposable of disposables) {
      disposable.dispose();
    }
    return initTutorialDocument(document.uri);
  });
};
const registerInteractiveTutorial = async (context) => {
  const disposables = [];
  const documentUri = setTutorialUri(context);
  let document = await initTutorialDocument(documentUri);
  let status = "stopped";
  let cleanup;
  const start = async () => {
    status = "starting";
    cleanup = await startTutorial(document);
    disposables.push(cleanup);
    status = "started";
  };
  const stop = async () => {
    cleanup == null ? void 0 : cleanup.dispose();
    status = "stopped";
  };
  disposables.push(
    window.onDidChangeVisibleTextEditors((editors) => {
      const tutorialIsVisible = editors.find(
        (editor) => editor.document.uri.toString() === documentUri.toString()
      );
      if (status === "starting") {
        return;
      }
      if (status === "started" && !tutorialIsVisible) {
        return stop();
      }
      if (status === "stopped" && tutorialIsVisible) {
        return start();
      }
      return;
    }),
    window.onDidChangeActiveTextEditor(async (editor) => {
      const tutorialIsActive = editor && editor.document.uri.toString() === documentUri.toString();
      return commands.executeCommand("setContext", "cody.tutorialActive", tutorialIsActive);
    }),
    workspace.onDidCloseTextDocument((document2) => {
      if (document2.uri !== documentUri) {
        return;
      }
      telemetryRecorder.recordEvent("cody.interactiveTutorial", "closed");
    }),
    commands.registerCommand("cody.tutorial.start", async () => {
      if (status === "started") {
        return window.showTextDocument(documentUri);
      }
      return start();
    }),
    commands.registerCommand("cody.tutorial.reset", async () => {
      telemetryRecorder.recordEvent("cody.interactiveTutorial", "reset");
      stop();
      document = await resetDocument(documentUri);
      return start();
    }),
    commands.registerCommand("cody.sidebar.tutorial", () => {
      logSidebarClick("tutorial");
      void commands.executeCommand("cody.tutorial.start");
    })
  );
  const tutorialVisible = window.visibleTextEditors.some(
    (editor) => editor.document.uri.toString() === documentUri.toString()
  );
  if (tutorialVisible) {
    await start();
  }
  return disposables;
};
export {
  registerInteractiveTutorial
};
