"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = registerCommentaryController;
exports.setTabReadonly = setTabReadonly;
var _path = require("path");
var _fetch = _interopRequireWildcard(require("./fetch"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
/*
 * Copyright 2020 The Kubernetes Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var __awaiter = void 0 && (void 0).__awaiter || function (thisArg, _arguments, P, generator) {
  function adopt(value) {
    return value instanceof P ? value : new P(function (resolve) {
      resolve(value);
    });
  }
  return new (P || (P = Promise))(function (resolve, reject) {
    function fulfilled(value) {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    }
    function rejected(value) {
      try {
        step(generator["throw"](value));
      } catch (e) {
        reject(e);
      }
    }
    function step(result) {
      result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
    }
    step((generator = generator.apply(thisArg, _arguments || [])).next());
  });
};
/**
 * commentary command usage
 */
/* const usage: UsageModel = {
  command: 'commentary',
  strict: 'commentary',
  example: 'commentary -f [<markdown file path>]',
  docs: 'Commentary',
  optional: [
    {
      name: '--title',
      alias: '-t',
      docs: 'Title for the commentary'
    },
    {
      name: '--base-url',
      alias: '-b',
      docs: 'Base URL for images'
    },
    {
      name: '--edit',
      docs: 'Open the UI in edit mode'
    },
    {
      name: '--header',
      docs: 'Show header text [Default: true]'
    },
    {
      name: '--preview',
      docs: 'Show a preview while editing [Default: true]'
    },
    {
      name: '--readonly',
      docs: 'Set the enclosing tab to be readonly'
    },
    {
      name: '--send',
      docs: 'Send edits to this channel (implies --no-header and --no-preview)'
    },
    {
      name: '--receive',
      docs: 'Consume edits from this channel (implies --no-header and --no-edit)'
    },
    {
      name: '--replace',
      docs: 'Replace all existing content in this tab'
    },
    {
      name: '--file',
      alias: '-f',
      docs: 'File that contains the texts'
    }
  ]
} */
function formatBaseUrl(filepath) {
  return __awaiter(this, void 0, void 0, function* () {
    if (/^http:/.test(filepath)) {
      const {
        format
      } = yield Promise.resolve().then(() => require('url'));
      const url = new URL(filepath);
      url.pathname = url.pathname.replace((0, _path.basename)(url.pathname), '{filename}');
      return format(url);
    } else {
      return filepath.replace((0, _path.basename)(filepath), '{filename}');
    }
  });
}
/** TODO: move to core Tab api? */
function setTabReadonly({
  tab
}) {
  return __awaiter(this, void 0, void 0, function* () {
    const [{
      eventBus
    }, {
      getPrimaryTabId
    }] = yield Promise.all([Promise.resolve().then(() => require('@kui-shell/core/mdist/api/Events')), Promise.resolve().then(() => require('@kui-shell/core/mdist/api/Tab'))]);
    eventBus.emitWithTabId('/kui/tab/edit/unset', getPrimaryTabId(tab));
  });
}
function addComment(args) {
  return __awaiter(this, void 0, void 0, function* () {
    const {
      edit: _edit,
      header: _header,
      preview: _preview,
      'snippet-base-path': snippetBasePath,
      receive,
      send,
      title,
      readonly,
      replace,
      simple
    } = args.parsedOptions;
    const filepath = args.parsedOptions.file || args.parsedOptions.f;
    const edit = receive !== undefined ? false : send !== undefined ? true : _edit;
    const header = receive !== undefined || send !== undefined ? false : _header;
    const preview = send !== undefined ? false : receive !== undefined ? true : _preview;
    // the markdown data either comes from a file, or directly from the
    // command line
    const {
      data = '#',
      codeBlockResponses
    } = filepath ? yield (0, _fetch.default)(filepath, args) // from file
    : {
      data: args.command // directly from command line
      .trim().slice(args.command.indexOf(' ') + 1).trim().replace(/\\n/g, '\n').replace(/\\t/g, '\t').replace(/--(no-)?(header|edit|preview|readonly|replace)\s*/g, '').replace(/(-t|--title|--send|--receive)\s+\S+\s*/g, '').replace(/^\\#/, '#') // escaped initial comment -> h1
      // this isn't perfect; e.g. it doesn't handle `commentary "hello" "world`; but it's a start
      .replace(/^"/, '').replace(/"$/, ''),
      codeBlockResponses: undefined
    };
    if (filepath && readonly) {
      setTabReadonly(args);
    }
    const baseUrl = args.parsedOptions['base-url'] ? (0, _fetch.join)(args.parsedOptions['base-url'], '{filename}') : filepath ? yield formatBaseUrl(filepath) : undefined;
    if (data !== undefined) {
      if (data === '#' || args.command === 'commentary') {
        return {
          apiVersion: 'kui-shell/v1',
          kind: 'CommentaryResponse',
          props: {
            edit,
            header,
            preview,
            replace,
            receive,
            send,
            simple,
            snippetBasePath,
            title,
            children: '',
            baseUrl
          }
        };
      } else {
        return {
          apiVersion: 'kui-shell/v1',
          kind: 'CommentaryResponse',
          props: {
            edit,
            header,
            preview,
            replace,
            receive,
            send,
            simple,
            snippetBasePath,
            title,
            filepath,
            children: data,
            codeBlockResponses,
            baseUrl
          }
        };
      }
    } else {
      throw new Error('Insufficient arguments: must specify either --file or -f, or provide a comment on the command line');
    }
  });
}
/**
 * This delegate is helpful to wrap the rendering of a given markdown
 * `filepath` in a maximized view that is injected as a replacement
 * for the current view.
 */
function delegate(args) {
  const delegate = args.argvNoOptions[2];
  const filepath = args.argvNoOptions[3];
  if (!delegate || !filepath) {
    throw new Error('Usage: commentary delegate <filepath>');
  }
  const children = `
---
layout:
    1:
        position: default
        maximized: true
---

\`\`\`shell
---
execute: now
outputOnly: true
maximize: true
---
${delegate} ${args.REPL.encodeComponent(filepath)}
\`\`\`
`;
  return {
    apiVersion: 'kui-shell/v1',
    kind: 'CommentaryResponse',
    props: {
      replace: true,
      children
    }
  };
}
/**
 * This plugin introduces the commentary command
 *
 */
function registerCommentaryController(commandTree) {
  const flags = {
    boolean: ['edit', 'header', 'preview', 'readonly', 'replace', 'simple']
  };
  commandTree.listen('/commentary', addComment, {
    outputOnly: true,
    flags
  });
  commandTree.listen('/#', addComment, {
    outputOnly: true,
    noCoreRedirect: true,
    flags
  });
  commandTree.listen('/commentary/delegate', delegate, {
    outputOnly: true,
    needsUI: true
  });
}