"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 JSON5 = require("json5");
const Observable_1 = require("rxjs/Observable");
const env_1 = require("../util/env");
require("rxjs/add/observable/of");
require("rxjs/add/operator/filter");
require("rxjs/add/operator/switchMap");
const http_error_service_1 = require("../http-error.service");
const project_1 = require("../redux/project");
const upload_schema_dialog_component_1 = require("./upload-schema-dialog.component");
/**
 * The UploadSchemaService saves the control schema from the editor to Mixer.
 */
let UploadSchemaService = class UploadSchemaService {
    constructor(project, store, dialog, http, httpErr, snackRef) {
        this.project = project;
        this.store = store;
        this.dialog = dialog;
        this.http = http;
        this.httpErr = httpErr;
        this.snackRef = snackRef;
    }
    /**
     * After confirmation, uploads the control schema from the studio to
     * Mixer.
     */
    upload() {
        this.confirmCanUpload()
            .filter(Boolean)
            .switchMap(() => this.uploadCurrentControls())
            .take(1)
            .toPromise()
            .then(() => this.snackRef.open('Schema uploaded', undefined, { duration: 2000 }))
            .catch(this.httpErr.joi(err => {
            // todo(connor4312): I would like to show these errors inline and
            // highlighted in the code editor, but doing so involves a notable
            // amount of work to parse into the right place. Toast for now.
            const { message, path } = err.details[0];
            this.snackRef.open(`Error uploading control: ${message} in "${path.join('.')}".`, undefined, { duration: 7000 });
        }))
            .catch(SyntaxError, err => {
            this.snackRef.open(`Your control schema contains errors: ${err.message}`);
        });
    }
    /**
     * Uploads the user's current control schema to their linked Interactive
     * version on Mixer. Can emit a SyntaxError if their current controls are bad.
     */
    uploadCurrentControls() {
        return this.store
            .take(1)
            .switchMap(s => this.http.post(env_1.apiUrl(`update-interactive-version/${s.sync.interactiveVersion.id}`), {
            controls: {
                scenes: JSON5.parse(s.code.scenes.join('\n')),
            },
        }))
            .map(() => undefined);
    }
    /**
     * Returns whether the user wants to upload their control scehma.
     */
    confirmCanUpload() {
        return this.store
            .map(s => s.sync.confirmSchemaUpload)
            .take(1)
            .switchMap(needsConfirm => {
            if (!needsConfirm) {
                return Observable_1.Observable.of(true);
            }
            return this.dialog
                .open(upload_schema_dialog_component_1.UploadSchemaDialogComponent)
                .afterClosed()
                .map((result) => {
                if (result.approved && result.dontShowAgain) {
                    this.project.syncDontConfirmSchema();
                }
                return result.approved;
            });
        });
    }
};
UploadSchemaService = __decorate([
    core_1.Injectable(),
    __metadata("design:paramtypes", [project_1.ProjectService,
        store_1.Store,
        material_1.MatDialog,
        http_1.Http,
        http_error_service_1.HttpErrorService,
        material_1.MatSnackBar])
], UploadSchemaService);
exports.UploadSchemaService = UploadSchemaService;
