/*
 * 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 = (this && this.__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')
 *
 */
import * as React from 'react';
import * as needle from 'needle';
import { eventChannelUnsafe, getCurrentTab, i18n } from '@kui-shell/core';
import { TagWidget } from '@kui-shell/plugin-client-common';
const strings = 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/, '');
}
export default 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 = getCurrentTab();
                if (!tab || !tab.REPL) {
                    if (tab && !tab.REPL) {
                        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 import(/* webpackMode: "lazy" */ '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(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);
        }
    }
}
//# sourceMappingURL=UpdateChecker.js.map