"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var React = _interopRequireWildcard(require("react"));

var needle = _interopRequireWildcard(require("needle"));

var _core = require("@kui-shell/core");

var _pluginClientCommon = require("@kui-shell/plugin-client-common");

function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (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 IBM Corporation
 *
 * 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());
  });
};
/*
 * For debugging, this will reset the dulyNoted bit:
 *
 * localStorage.removeItem('kui-shell.org/UpdateChecker/DulyNoted')
 *
 */


const strings = (0, _core.i18n)('plugin-core-support');
/** Releases page */

const RELEASE = tag => `https://github.com/IBM/kui/releases/tag/v${tag}`;
/** Releases feed */


const FEED = 'https://github.com/IBM/kui/releases.atom';
/** By default, check for updates once a day */

const DEFAULT_INTERVAL = 24 * 60 * 60 * 1000;
/** By default, wait 5 minutes after statup for the first check */

const DEFAULT_LAG = 0; // 5 * 60 * 1000

/** Remember that the version "duly noted" the availability of particular version in localStorage, using this key */

const DULY_NOTED_KEY = 'kui-shell.org/UpdateChecker/DulyNoted';
/**
 * GitHub gives back "v8.10.0" and the Kui version command gives back "8.10.0".
 *
 * @see https://github.com/IBM/kui/issues/4918
 *
 */

function stripOffPrefixV(githubVersionString) {
  return githubVersionString.replace(/^v/, '');
}

class UpdateChecker extends React.PureComponent {
  constructor(props) {
    super(props);
    setTimeout(() => this.checkForUpdates(), this.props.lag || DEFAULT_LAG);
    this.state = {
      pinger: this.initPinger(),
      currentVersion: undefined,
      latestVersion: undefined,
      dulyNoted: localStorage.getItem(DULY_NOTED_KEY)
    };
  }
  /** Initialize a timer that periodically checks for updates */


  initPinger() {
    return setInterval(() => {
      this.checkForUpdates();
    }, this.props.interval || DEFAULT_INTERVAL);
  }
  /** Ping the release feed to check for the latest release */


  checkForUpdates() {
    needle('get', FEED, {
      json: true
    }).then(res => {
      return res.body.children.filter(_ => _.name === 'entry')[0].children.find(_ => _.name === 'title').value;
    }).then(stripOffPrefixV) // see https://github.com/IBM/kui/issues/4918
    .then(latestVersion => this.setState(curState => ({
      latestVersion,
      dulyNoted: curState.dulyNoted && curState.dulyNoted !== latestVersion ? undefined : curState.dulyNoted
    }))).catch(err => {
      console.error('error checking for updates', err);
    });
  }
  /** What version are we running? */


  getCurrentVersion() {
    return __awaiter(this, void 0, void 0, function* () {
      if (!this.state.currentVersion) {
        const tab = (0, _core.getCurrentTab)();

        if (!tab || !tab.REPL) {
          if (tab && !tab.REPL) {
            _core.eventChannelUnsafe.once(`/tab/new/${tab.uuid}`, () => this.getCurrentVersion());
          }

          return;
        }

        const currentVersion = yield tab.REPL.qexec('version');
        this.setState({
          currentVersion
        });
      }
    });
  }

  componentDidMount() {
    this.getCurrentVersion();
  }
  /** Bye! */


  componentWillUnmount() {
    if (this.state.pinger) {
      clearInterval(this.state.pinger);
    }
  }
  /** Given current state, is an update available? */


  isUpdateAvailable() {
    return this.state.latestVersion && this.state.currentVersion !== this.state.latestVersion && this.state.latestVersion !== this.state.dulyNoted;
  }
  /** Text for update available notification */


  text() {
    return this.isUpdateAvailable() ? strings('Update available', this.state.latestVersion) : '';
  }
  /** User has acknoledged the notification  */


  dulyNoted() {
    return __awaiter(this, void 0, void 0, function* () {
      try {
        localStorage.setItem(DULY_NOTED_KEY, this.state.latestVersion);
        const {
          shell
        } = yield Promise.resolve().then(() => require('electron'));
        shell.openExternal(RELEASE(this.state.latestVersion));
      } catch (err) {
        console.error('Error opening releases page');
      }

      this.setState({
        dulyNoted: this.state.latestVersion
      });
    });
  }

  render() {
    if (this.isUpdateAvailable()) {
      return React.createElement(_pluginClientCommon.TagWidget, {
        id: "kui--plugin-core-support--update-checker",
        title: strings('Version X is available. Click to see the changelog and download the new release.', this.state.latestVersion),
        onClick: () => this.dulyNoted()
      }, this.text());
    } else {
      return React.createElement(React.Fragment, null);
    }
  }

}

exports.default = UpdateChecker;