"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("@angular/core");
const http_1 = require("@angular/http");
const material_1 = require("@angular/material");
const store_1 = require("@ngrx/store");
const http_error_service_1 = require("./http-error.service");
const rename_bundle_dialog_component_1 = require("./rename-bundle-dialog/rename-bundle-dialog.component");
const env_1 = require("./util/env");
/**
 * Thrown internally if the eval check fails.
 */
class HasEvalError extends Error {
    constructor() {
        super('eval is not allowed');
        if (Object.setPrototypeOf) {
            Object.setPrototypeOf(this, HasEvalError.prototype);
            return;
        }
        this.__proto__ = HasEvalError.prototype;
    }
}
/**
 * The BundleUploadService triggers the dev server to bundle and save the
 * custom control set to the Interactive studio.
 */
let BundleUploadService = class BundleUploadService {
    constructor(store, http, snackRef, dialog, httpErr) {
        this.store = store;
        this.http = http;
        this.snackRef = snackRef;
        this.dialog = dialog;
        this.httpErr = httpErr;
    }
    /**
     * Upload starts a bundle upload. The promise resolve when the process
     * completes, or the user is shown an error.
     */
    upload() {
        const snack = this.snackRef.open('Bundling and uploading controls...');
        return this.http
            .get(env_1.apiUrl('ensure-no-eval'))
            .switchMap(res => {
            if (res.json().hasEval) {
                throw new HasEvalError();
            }
            return this.store;
        })
            .take(1)
            .toPromise()
            .then(s => this.http
            .post(env_1.apiUrl(`start-version-upload/${s.sync.interactiveVersion.id}`), {})
            .toPromise())
            .then(() => {
            this.snackRef.open('Bundle uploaded successfully', undefined, { duration: 3000 });
        })
            .finally(() => {
            snack.dismiss();
        })
            .catch(this.httpErr.catch('BundleNameTakenError', () => this.renameBundle()))
            .catch(HasEvalError, () => {
            this.notifyNoEval();
        })
            .catch(err => {
            this.showGenericError(err);
        });
    }
    /**
     * Displays a generic unknown error in a toast.
     */
    showGenericError(err) {
        const errSnack = this.snackRef.open('Error uploading bundle', 'View Error', {
            duration: 10000,
        });
        errSnack.onAction().subscribe(() => {
            window.open('about:blank').document.body.innerHTML += err.text ? err.text() : err.stack;
        });
    }
    /**
     * Prompts the user to rename their bundle, rerunning the upload on success.
     */
    renameBundle() {
        return this.dialog
            .open(rename_bundle_dialog_component_1.RenameBundleDialogComponent)
            .afterClosed()
            .toPromise()
            .then(ok => {
            if (ok) {
                return this.upload();
            }
            return undefined;
        });
    }
    /**
     * Notifies the user that they cannot use eval functions in their bundle.
     */
    notifyNoEval() {
        const errSnack = this.snackRef.open('You cannot use eval() in control bundles. Run "miix upload" ' +
            'from the command line for details.', 'Read Why', { duration: 10000 });
        errSnack.onAction().subscribe(() => window.open('https://aka.ms/dont-be-eval'));
    }
};
BundleUploadService = __decorate([
    core_1.Injectable(),
    __metadata("design:paramtypes", [store_1.Store,
        http_1.Http,
        material_1.MatSnackBar,
        material_1.MatDialog,
        http_error_service_1.HttpErrorService])
], BundleUploadService);
exports.BundleUploadService = BundleUploadService;
