'use strict';

var projectsServiceClass = Class.extend({
    MODULE_URL: MP_SITE_URL + '/build_app/projects',

    create: function (project) {
        return this.$http.post(this.MODULE_URL + '/project', project, {cache: false});
    },

    update: function (id, project) {
        return this.$http.put(`${this.MODULE_URL}/project/${id}`, project, {cache: false});
    },

    delete: function (id) {
        return this.$http.delete(`${this.MODULE_URL}/project/${id}`, {cache: false});
    },

    push: function (id, project) {
        return this.$http.post(`${this.MODULE_URL}/push/${id}`, project, {cache: false});
    },

    localDeploy: async function (id, project) {
        return this.$http.post(`${this.MODULE_URL}/localDeploy/${id}`, project, {cache: false});
    },

    synchronizeVcsWithProject: function (id, localDeploy) {
        return this.$http.post(`${this.MODULE_URL}/synchronize/${id}?localDeploy=${localDeploy ? 'true' : 'false'}`, {cache: false});
    },

    isProjectSynchronizedWithVcs: async function (id) {
        let response = await this.$http.get(`${this.MODULE_URL}/vcsSynchronized/${id}`, {cache: false});
        return response.data;
    },

    anyProjectDeployed: function () {
        return  this.$http.get(`${this.MODULE_URL}/anyProjectDeployed`, {cache: false});
    },

    get: function (id) {
        return this.$http.get(`${this.MODULE_URL}/project/${id}`, {cache: false});
    },

    list: function (limit = 10) {
        return this.$http.get(`${this.MODULE_URL}/list?limit=${limit}`, {cache: false});
    },

    createLocal: function (data) {
        return this.$http.post(this.MODULE_URL + '/local_project', data);
    },

    getModules: function (id) {
        return this.$http.get(`${this.MODULE_URL}/modules/${id}`, {cache: false});
    },

    addModule: function (projectId, name, version) {
        return this.$http.post(`${this.MODULE_URL}/module/${projectId}/${name}/${version}`, {cache: false});
    },

    addModuleByUrl: function (projectId, url) {
        return this.$http.post(`${this.MODULE_URL}/module_by_url/${projectId}`, { url }, {cache: false});
    },

    updateModule: function (projectId, name, version) {
        return this.$http.put(`${this.MODULE_URL}/module/${projectId}/${name}/${version}`, {cache: false});
    },

    removeModule: function (projectId, name, encodedName = false) {
        return this.$http.delete(`${this.MODULE_URL}/module/${projectId}/${name}/?encodedName=${encodedName ? 'true' : 'false'}`, {cache: false});
    },

    getModuleInput: function (projectId, name, encodedName = false) {
        return this.$http.get(
            `${this.MODULE_URL}/module_input/${projectId}/${name}/?encodedName=${encodedName ? 'true' : 'false'}`,
            {cache: false}
        );
    },

    setModuleInput: function (projectId, name, data, encodedName = false) {
        return this.$http.post(
            `${this.MODULE_URL}/module_input/${projectId}/${name}/?encodedName=${encodedName ? 'true' : 'false'}`,
            data,
            {cache: false}
        );
    },

    refresh: function (id) {
        return this.$http.post(`${this.MODULE_URL}/refresh/${id}`, {cache: false});
    },

    forcePull: function (id) {
        return this.$http.post(`${this.MODULE_URL}/forcePull/${id}`, {cache: false});
    },

    rebase: function (id) {
        return this.$http.post(`${this.MODULE_URL}/rebase/${id}`, {cache: false});
    },

    forceRebase: function (id) {
        return this.$http.post(`${this.MODULE_URL}/forceRebase/${id}`, {cache: false});
    },

    _getProjectsAhead: function () {
        let projects = window.localStorage.getItem('projects_ahead');
        return projects ? projects.split(',') : [];
    },
    setAhead: function (id) {
        let projects = this._getProjectsAhead();
        if (!projects.includes(id)) {
            projects.push(id);
        }
        window.localStorage.setItem('projects_ahead', projects.join(','))
        document.dispatchEvent(new Event('project_ahead_changed'));
    },

    removeAhead: function (id) {
        let projects = this._getProjectsAhead();
        if (projects.includes(id)) {
            projects.splice(projects.indexOf(id), 1);
        }
        window.localStorage.setItem('projects_ahead', projects.join(','))
        document.dispatchEvent(new Event('project_ahead_changed'));
    },

    isProjectAhead: function (id) {
        return (this._getProjectsAhead()).includes(id)
    },

    deploy: async function (id, localDeploy = false) {
        await this.synchronizeVcsWithProject(id, localDeploy);

        const hubKey = await this.getHubKey();
        const updateClass = "default:cfengine_internal_masterfiles_update";
        const cmdbItems = await this.cmdbService.getItems(hubKey);

        if (!cmdbItems.data.value || !cmdbItems.data.value.classes.hasOwnProperty(updateClass)) {
            await this.cmdbService.createItem(
                hubKey,
                'classes',
                updateClass,
                {"comment": "Update default policy distribution point from upstream repository."}
            );
            // agent run to set host specific data
            await this.actionService.agentRun(hubKey);
        }

        // agent run to run masterfiles-stage.sh ( bundle cfe_internal_update_from_repository )
        await this.actionService.agentRun(hubKey);
    },

    stopDeploying: async function () {
        await this.cmdbService.deleteItem(
            (await this.getHubKey()),
            'classes',
            'default:cfengine_internal_masterfiles_update'
        );

        await this.clearVCS();
    },

    getHubKey: async function () {
        const hubInfo = await this.hubManagementService.getHubInfo();
        const hubKey = hubInfo.data.hostkey || null;
        if (hubKey == null) {
            throw {
                data: "Cannot get the Hub key to write needed CMDB data for deployment. " +
                    "Please ensure that Hub is reported and re-bootstrap if not."
            };
        }
        return hubKey;
    },

    clearVCS: function () {
        return this.$http.post('/settingsApi/clearVCS', {cache: false});
    },

    setDefaultAction: function (id, action) {
        return this.$http.post(`${this.MODULE_URL}/defaultAction/${id}`, {action}, {cache: false});
    }

});

(function () {
    const projectsServiceClassProvider = Class.extend({
        instance: new projectsServiceClass(),
        $get: ['$http' , 'cmdbService', 'hubManagementService', 'actionService',
            function ($http, cmdbService, hubManagementService, actionService) {
                this.instance.$http = $http;
                this.instance.cmdbService = cmdbService;
                this.instance.hubManagementService = hubManagementService;
                this.instance.actionService = actionService;
                return this.instance;
        }]
    });

    angular.module('projectsServiceModule', []).provider('projectsService', projectsServiceClassProvider);
}());
