import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/inherits";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
import _regeneratorRuntime from "@babel/runtime/regenerator";
/* eslint-disable @atlaskit/design-system/ensure-design-token-usage */
import React from 'react';
import { unzip, HTTPRangeReader } from 'unzipit';
import { FormattedMessage } from 'react-intl-next';
import { CustomMediaPlayer, messages } from '@atlaskit/media-ui';
import { getLanguageType, isCodeViewerItem } from '@atlaskit/media-ui/codeViewer';
import { Text } from '@atlaskit/primitives/compiled';
import { Outcome } from '../../domain';
import { CustomVideoPlayerWrapper, AudioPlayer, CustomAudioPlayerWrapper, DefaultCoverWrapper, ListWrapper } from '../../styleWrappers';
import AudioIcon from '@atlaskit/icon/core/migration/audio--media-services-audio';
import ErrorMessage from '../../errorMessage';
import { BaseViewer } from '../base-viewer';
import { InteractiveImg } from '../image/interactive-img';
import { PDFRenderer } from '../doc/pdfRenderer';
import { ArchiveItemViewerWrapper, ArchiveLayout, ArchiveViewerWrapper } from './styleWrappers';
import ArchiveSidebarRenderer from './archive-sidebar-renderer';
import { getMediaTypeFromFilename, getMimeTypeFromFilename, rejectAfter } from '../../utils';
import { Spinner } from '../../loading';
import { ENCRYPTED_ENTRY_ERROR_MESSAGE } from './consts';
import { withAnalyticsEvents } from '@atlaskit/analytics-next';
import { fireAnalytics } from '../../analytics';
import { ArchiveViewerError, isMediaViewerError } from '../../errors';
import { createZipEntryLoadSucceededEvent } from '../../analytics/events/operational/zipEntryLoadSucceeded';
import { createZipEntryLoadFailedEvent } from '../../analytics/events/operational/zipEntryLoadFailed';
import { CodeViewRenderer } from '../codeViewer/codeViewerRenderer';
import { DEFAULT_LANGUAGE } from '../codeViewer/util';
import { MAX_FILE_SIZE_SUPPORTED_BY_CODEVIEWER } from '../../item-viewer';
export var getArchiveEntriesFromFileState = /*#__PURE__*/function () {
  var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(fileState, mediaClient, collectionName) {
    var url, reader, archive;
    return _regeneratorRuntime.wrap(function _callee$(_context) {
      while (1) switch (_context.prev = _context.next) {
        case 0:
          _context.next = 2;
          return mediaClient.file.getFileBinaryURL(fileState.id, collectionName);
        case 2:
          url = _context.sent;
          reader = new HTTPRangeReader(url);
          _context.next = 6;
          return rejectAfter(function () {
            return unzip(reader);
          });
        case 6:
          archive = _context.sent;
          return _context.abrupt("return", archive);
        case 8:
        case "end":
          return _context.stop();
      }
    }, _callee);
  }));
  return function getArchiveEntriesFromFileState(_x, _x2, _x3) {
    return _ref.apply(this, arguments);
  };
}();
export var ArchiveViewerBase = /*#__PURE__*/function (_BaseViewer) {
  function ArchiveViewerBase() {
    var _this;
    _classCallCheck(this, ArchiveViewerBase);
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }
    _this = _callSuper(this, ArchiveViewerBase, [].concat(args));
    _defineProperty(_this, "onError", function (error, entry) {
      _this.props.onError(error);
      _this.setState({
        content: Outcome.successful(_objectSpread(_objectSpread({}, _this.state.content.data), {}, {
          selectedArchiveEntry: entry,
          error: error
        }))
      });
    });
    _defineProperty(_this, "onSelectedArchiveEntryChange", /*#__PURE__*/function () {
      var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(selectedArchiveEntry) {
        var src, codeViewerSrc, isCodeMimeType, blob;
        return _regeneratorRuntime.wrap(function _callee2$(_context2) {
          while (1) switch (_context2.prev = _context2.next) {
            case 0:
              _this.setState({
                content: Outcome.successful(_objectSpread(_objectSpread({}, _this.state.content.data), {}, {
                  selectedArchiveEntry: undefined,
                  hasLoadedEntries: false // displays a nice loading spinner for the content viewer
                }))
              });
              src = '';
              codeViewerSrc = '';
              isCodeMimeType = isCodeViewerItem(selectedArchiveEntry.name, getMimeTypeFromFilename(selectedArchiveEntry.name));
              if (selectedArchiveEntry.isDirectory) {
                _context2.next = 19;
                break;
              }
              _context2.prev = 5;
              _context2.next = 8;
              return rejectAfter(function () {
                return selectedArchiveEntry.blob();
              }, 10000);
            case 8:
              blob = _context2.sent;
              src = URL.createObjectURL(blob);
              if (!isCodeMimeType) {
                _context2.next = 14;
                break;
              }
              _context2.next = 13;
              return rejectAfter(function () {
                return blob.text();
              });
            case 13:
              codeViewerSrc = _context2.sent;
            case 14:
              _context2.next = 19;
              break;
            case 16:
              _context2.prev = 16;
              _context2.t0 = _context2["catch"](5);
              return _context2.abrupt("return", _this.onError(new ArchiveViewerError(_context2.t0.message === ENCRYPTED_ENTRY_ERROR_MESSAGE ? 'archiveviewer-encrypted-entry' : 'archiveviewer-create-url', _context2.t0), selectedArchiveEntry));
            case 19:
              _this.setState({
                content: Outcome.successful(_objectSpread(_objectSpread({}, _this.state.content.data), {}, {
                  selectedArchiveEntry: selectedArchiveEntry,
                  src: src,
                  name: selectedArchiveEntry.name,
                  isDirectory: selectedArchiveEntry.isDirectory,
                  error: undefined,
                  codeViewerSrc: codeViewerSrc,
                  isCodeMimeType: isCodeMimeType,
                  hasLoadedEntries: true
                }))
              });
            case 20:
            case "end":
              return _context2.stop();
          }
        }, _callee2, null, [[5, 16]]);
      }));
      return function (_x4) {
        return _ref2.apply(this, arguments);
      };
    }());
    _defineProperty(_this, "onHeaderClicked", function () {
      // This will set the preview to show the Folder icon
      _this.setState({
        content: Outcome.successful(_objectSpread({}, _this.state.content.data))
      });
    });
    _defineProperty(_this, "onViewerLoad", function (selectedArchiveEntry) {
      return function () {
        fireAnalytics(createZipEntryLoadSucceededEvent(_this.props.item, selectedArchiveEntry), _this.props.createAnalyticsEvent);
      };
    });
    _defineProperty(_this, "onViewerError", function (primaryErrorReason, selectedArchiveEntry) {
      return function (error) {
        return error && isMediaViewerError(error) ? _this.onError(new ArchiveViewerError(primaryErrorReason, error.secondaryError, selectedArchiveEntry)) : _this.onError(new ArchiveViewerError(primaryErrorReason, error, selectedArchiveEntry));
      };
    });
    _defineProperty(_this, "onSidebarLoaded", function () {
      _this.setState({
        content: Outcome.successful(_objectSpread(_objectSpread({}, _this.state.content.data), {}, {
          hasLoadedEntries: true
        }))
      });
      _this.props.onSuccess();
    });
    return _this;
  }
  _inherits(ArchiveViewerBase, _BaseViewer);
  return _createClass(ArchiveViewerBase, [{
    key: "init",
    value: function () {
      var _init = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
        return _regeneratorRuntime.wrap(function _callee3$(_context3) {
          while (1) switch (_context3.prev = _context3.next) {
            case 0:
              this.setState(this.initialState);
            case 1:
            case "end":
              return _context3.stop();
          }
        }, _callee3, this);
      }));
      function init() {
        return _init.apply(this, arguments);
      }
      return init;
    }()
  }, {
    key: "initialState",
    get: function get() {
      return {
        content: Outcome.successful({
          src: '',
          name: '',
          isDirectory: true
        })
      };
    }
  }, {
    key: "release",
    value: function release() {
      var content = this.state.content;
      if (!content.data || !content.data.src) {
        return;
      }
      URL.revokeObjectURL(content.data.src);
    }
  }, {
    key: "renderSuccessful",
    value: function renderSuccessful(content) {
      var _this$props = this.props,
        item = _this$props.item,
        mediaClient = _this$props.mediaClient,
        collectionName = _this$props.collectionName;
      var selectedArchiveEntry = content.selectedArchiveEntry,
        hasLoadedEntries = content.hasLoadedEntries;
      var hasSelectedArchiveEntry = selectedArchiveEntry !== undefined;
      return /*#__PURE__*/React.createElement(ArchiveLayout, null, /*#__PURE__*/React.createElement(ArchiveSidebarRenderer, {
        selectedFileState: item,
        mediaClient: mediaClient,
        onSelectedArchiveEntryChange: this.onSelectedArchiveEntryChange,
        onHeaderClicked: this.onHeaderClicked,
        isArchiveEntryLoading: !hasSelectedArchiveEntry,
        collectionName: collectionName,
        onError: this.onError,
        onSuccess: this.onSidebarLoaded
      }), /*#__PURE__*/React.createElement(ArchiveViewerWrapper, null, !hasSelectedArchiveEntry && !hasLoadedEntries ? /*#__PURE__*/React.createElement(ListWrapper, null, /*#__PURE__*/React.createElement(Spinner, null)) : this.renderArchiveItemViewer(content)));
    }
  }, {
    key: "renderArchiveItemViewer",
    value: function renderArchiveItemViewer(content) {
      var _this$props2 = this.props,
        item = _this$props2.item,
        viewerOptions = _this$props2.viewerOptions;
      var src = content.src,
        name = content.name,
        isDirectory = content.isDirectory,
        error = content.error,
        selectedArchiveEntry = content.selectedArchiveEntry,
        codeViewerSrc = content.codeViewerSrc,
        isCodeMimeType = content.isCodeMimeType;
      if (error) {
        return this.renderPreviewError(error, selectedArchiveEntry);
      }
      if (!isDirectory && selectedArchiveEntry) {
        var _viewerOptions$custom;
        if (!name || !src) {
          return this.renderPreviewError(new ArchiveViewerError('archiveviewer-missing-name-src'), selectedArchiveEntry);
        }
        var customRenderer = viewerOptions === null || viewerOptions === void 0 || (_viewerOptions$custom = viewerOptions.customRenderers) === null || _viewerOptions$custom === void 0 ? void 0 : _viewerOptions$custom.find(function (renderer) {
          return renderer.shouldUseCustomRenderer({
            fileItem: item,
            archiveFileItem: {
              name: name
            }
          });
        });
        if (customRenderer) {
          return /*#__PURE__*/React.createElement(ArchiveItemViewerWrapper, null, customRenderer.renderContent({
            fileItem: item,
            archiveFileItem: {
              name: name
            },
            getBinaryContent: function () {
              var _getBinaryContent = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
                return _regeneratorRuntime.wrap(function _callee4$(_context4) {
                  while (1) switch (_context4.prev = _context4.next) {
                    case 0:
                      _context4.next = 2;
                      return fetch(src);
                    case 2:
                      return _context4.abrupt("return", _context4.sent.blob());
                    case 3:
                    case "end":
                      return _context4.stop();
                  }
                }, _callee4);
              }));
              function getBinaryContent() {
                return _getBinaryContent.apply(this, arguments);
              }
              return getBinaryContent;
            }(),
            onLoad: this.onViewerLoad(selectedArchiveEntry),
            onError: this.onViewerError('archiveviewer-customrenderer-onerror', selectedArchiveEntry)
          }));
        }
        var mediaType = getMediaTypeFromFilename(name);
        if (isCodeMimeType) {
          // Same code viewer logic as in Item-Viewer.tsx
          // Render error message if code file has size over 10MB.
          // Required by https://product-fabric.atlassian.net/browse/MEX-1788
          if ((selectedArchiveEntry === null || selectedArchiveEntry === void 0 ? void 0 : selectedArchiveEntry.size) > MAX_FILE_SIZE_SUPPORTED_BY_CODEVIEWER) {
            return this.renderPreviewError(new ArchiveViewerError('archiveviewer-codeviewer-file-size-exceeds'), selectedArchiveEntry);
          }
          return /*#__PURE__*/React.createElement(CodeViewRenderer, {
            onSuccess: this.onViewerLoad(selectedArchiveEntry),
            onError: this.onViewerError('archiveviewer-codeviewer-onerror', selectedArchiveEntry),
            item: item,
            src: codeViewerSrc || '',
            language: getLanguageType(name) || DEFAULT_LANGUAGE
          });
        }
        switch (mediaType) {
          case 'image':
            return /*#__PURE__*/React.createElement(ArchiveItemViewerWrapper, null, /*#__PURE__*/React.createElement(InteractiveImg, {
              src: src,
              alt: name,
              onLoad: this.onViewerLoad(selectedArchiveEntry),
              onError: this.onViewerError('archiveviewer-imageviewer-onerror', selectedArchiveEntry)
            }));
          case 'video':
            return /*#__PURE__*/React.createElement(ArchiveItemViewerWrapper, null, /*#__PURE__*/React.createElement(CustomVideoPlayerWrapper, {
              "data-testid": "media-viewer-video-content"
            }, /*#__PURE__*/React.createElement(CustomMediaPlayer, {
              type: "video",
              isAutoPlay: false,
              src: src,
              onCanPlay: this.onViewerLoad(selectedArchiveEntry),
              onError: this.onViewerError('archiveviewer-videoviewer-onerror', selectedArchiveEntry)
            })));
          case 'audio':
            return /*#__PURE__*/React.createElement(ArchiveItemViewerWrapper, null, /*#__PURE__*/React.createElement(AudioPlayer, {
              "data-testid": "media-viewer-audio-content"
            }, /*#__PURE__*/React.createElement(DefaultCoverWrapper, null, /*#__PURE__*/React.createElement(AudioIcon, {
              label: "cover",
              LEGACY_size: "xlarge",
              color: "currentColor"
              // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage
              ,
              LEGACY_primaryColor: "#22272B"
              // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage
              ,
              LEGACY_secondaryColor: "#9FADBC"
            })), /*#__PURE__*/React.createElement(CustomAudioPlayerWrapper, null, /*#__PURE__*/React.createElement(CustomMediaPlayer, {
              type: "audio",
              isAutoPlay: false,
              src: src,
              onCanPlay: this.onViewerLoad(selectedArchiveEntry),
              onError: this.onViewerError('archiveviewer-audioviewer-onerror', selectedArchiveEntry)
            }))));
          case 'doc':
            return /*#__PURE__*/React.createElement(ArchiveItemViewerWrapper, null, /*#__PURE__*/React.createElement(PDFRenderer, {
              item: item,
              src: src,
              onSuccess: this.onViewerLoad(selectedArchiveEntry),
              onError: this.onViewerError('archiveviewer-docviewer-onerror', selectedArchiveEntry)
            }));
          case 'archive':
            //BMPT-388 - Add illustration here, currently empty viewer
            return /*#__PURE__*/React.createElement(ArchiveItemViewerWrapper, null);
          default:
            return this.renderPreviewError(new ArchiveViewerError('archiveviewer-unsupported'), selectedArchiveEntry);
        }
      }
    }
  }, {
    key: "renderPreviewError",
    value: function renderPreviewError(error, entry) {
      var _this$props3 = this.props,
        item = _this$props3.item,
        createAnalyticsEvent = _this$props3.createAnalyticsEvent;
      fireAnalytics(createZipEntryLoadFailedEvent(item, error, entry), createAnalyticsEvent);
      return /*#__PURE__*/React.createElement(ListWrapper, null, /*#__PURE__*/React.createElement(ErrorMessage, {
        fileId: item.id,
        fileState: item,
        error: error,
        supressAnalytics: true
      }, /*#__PURE__*/React.createElement(Text, null, /*#__PURE__*/React.createElement(FormattedMessage, messages.try_downloading_file))));
    }
  }]);
}(BaseViewer);
export var ArchiveViewer = withAnalyticsEvents()(ArchiveViewerBase);