'use strict';

const initSaveReportScope = function ($scope, commonHelper) {
    $scope.reportType = "compliance";
    $scope.savedSearchName = {};
    $scope.savedSearchCategory = {};
    $scope.savedSearchCategory.input = 'compliance_report';
    $scope.reportCategory = 'Compliance';
    $scope.saveReportTitle = 'Save report';
    $scope.reportCategories = ReportCategories;

    $scope.is_public = {};
    $scope.is_public.input = true;
    $scope.reportRolesTMP = {};
    $scope.reportRoles = {};
    $scope.categorySelectDisabled = true;

    $scope.roles = commonHelper.getRolesArray();
    $scope.is_admin = commonHelper.checkifAdmin($scope.roles);
};

const groupConditionsByCategory = ($scope, savedConditions, commonHelper) => {
    $scope.savedConditions = {}

    if (!Array.isArray(savedConditions)) {
        savedConditions = Object.values(savedConditions).flat();
    }
    savedConditions.forEach(item => {
        if (!$scope.savedConditions[item.category]) {
            $scope.savedConditions[item.category] = [];
        }
        $scope.savedConditions[item.category].push(item);
    })
    $scope.savedConditions = commonHelper.sortObjectByKey($scope.savedConditions);

}
const loadConditions = function ($scope, rulesService, commonHelper) {
    if ($scope.conditionIds.length > 0) {
        rulesService.getrules($scope.conditionIds).then(data => {
            groupConditionsByCategory($scope, data.data, commonHelper);
        });
    }
};

BaseController.$inject = ['$scope'];
const complianceMainController = BaseController.extend({
    init: function ($scope, $location, rulesService, modalWindowService, commonHelper, reportService, paginationService, $routeParams, complianceHelper, globalHelper) {
        let self = this;
        this._super($scope);
        this.$location = $location;
        this.$routeParams = $routeParams;
        this.rulesService = rulesService;
        this.reportService = reportService;
        this.commonHelper = commonHelper;
        this.globalHelper = globalHelper;
        this.$scope.modalWindow = modalWindowService;
        this.$scope.complianceHelper = complianceHelper;
        this.$scope.paginator = paginationService;

        this.$scope.instance = "complianceMainController";
        this.$scope.reports_loaded = true;
        this.$scope.ownReports = false;

        self.commonHelper._setVIEWVariables(self.$scope);

        this.loadReports();
    },

    defineScope: function () {
        this.$scope.createReport = this.createReport.bind(this);
        this.$scope.editConditions = this.editConditions.bind(this);
        this.$scope.import = this.import.bind(this);
        this.$scope.isEmptyObj = this.isEmptyObj.bind(this);
        this.$scope.sortReorder = this.sortReorder.bind(this);
        this.$scope.deleteReport = this.deleteReport.bind(this);
        this.$scope.deleteConfirm = this.deleteConfirm.bind(this);
        this.$scope.getUserName = this.getUserName.bind(this);
    },

    defineListeners: function () {
        let self = this;

        self.$scope.$on('paginatorChange', function () {
            self.loadReports();
        });

        self.$scope.$watch('ownReports', function () {
            self.loadReports();
        });

        /**
         * watch saved report
         * if changed then load score
         */
        self.$scope.$watch('savedReports', function () {
            let ids = Object.keys(self.$scope.savedReports).map(index => self.$scope.savedReports[index].id);
            if (ids.length > 0) {
                self.reportService.getComplianceScore(ids).then(result => {
                    const scores = result.data;
                    Object.keys(self.$scope.savedReports).forEach(index => {
                        const id = self.$scope.savedReports[index].id;
                        self.$scope.savedReports[index].score = scores[id] != undefined ? scores[id].score : 'n/a';
                    });
                })
            }
        }, true);
    },

    loadReports: function () {
        let self = this;
        self.$scope.reports_loaded = false;
        self.$scope.savedReports = {};

        let params = $.param({
            page: (self.$scope.paginator.page !== undefined ? self.$scope.paginator.page : 1),
            limit: self.$scope.paginator.rowsPerPage,

            reportCategory: self.$scope.selectedCategories,
            sortColumn: (self.$scope.VIEW.sortColumn !== undefined && self.$scope.VIEW.sortColumn != '' ? self.$scope.VIEW.sortColumn : 'label'),
            sortDescending: (self.$scope.VIEW.sortDescending !== undefined && self.$scope.VIEW.sortDescending != '' ? self.$scope.VIEW.sortDescending : '0'),

            type: 'compliance',
            tab: self.$scope.ownReports ? 'my' : '',
            isPublic: 1,
        });

        self.reportService.loadReports(params).then(
            function (result) {
                let data = result.data;
                self.$scope.savedReports = data.items;
                self.$scope.paginator.refreshPaginator(data.total);
                if (self.$scope.paginator.page > self.$scope.paginator.pages) {
                    self.$scope.paginator.reloadView(self.$scope.paginator.pages);
                }
                self.$scope.reports_loaded = true;
            },
            function (error) {
                self.$scope.reports_loaded = true;
            });
    },

    sortReorder: function (col) {
        let self = this;
        angular.forEach(self.$scope.VIEW.tablehead, function (el) {
            if (el.nameToSort == col) {
                el.sort = el.sort > 0 ? -1 : 1;
                self.$scope.VIEW.sortColumn = el.name;
                self.$scope.VIEW.sortDescending = el.sort > 0 ? 0 : 1;
            } else {
                el.sort = null;
            }
        });

        if (self.$scope.VIEW.sortColumn !== undefined && self.$scope.VIEW.sortColumn !== '') {
            self.loadReports();
        }
    },

    deleteReport: function (id) {
        var self = this;
        self.$scope.modalWindow.close();
        self.reportService.deleteReport(id).then(
            function () {
                self.loadReports();
            },
            function (error) {
                notify.error(error.data);
            });
    },

    deleteConfirm: function (reportId) {
        this.$scope.selectedReport = reportId;
        this.$scope.modalWindow.open('deleteConfirm', this.$scope);
    },

    createReport: function () {
        document.location.href = '/reports/complianceReport/create_report';
    },

    editConditions: function () {
        this.$location.path('/compliance/edit_conditions');
    },

    import: function () {
        this.$location.path('/compliance/import');
    },

    isEmptyObj: function (obj) {
        return angular.equals({}, obj);
    },

    getUserName: function (row) {
        return this.globalHelper.getUserName(row.meta_data.source, row.username)
    }

});

complianceMainController.$inject = ['$scope', '$location', 'rulesService', 'modalWindowService', 'commonHelper', 'reportService', 'paginationService', '$routeParams', 'complianceHelper', 'globalHelper'];

const complianceCreateEditController = BaseController.extend({

    init: function ($scope, $location, rulesService, modalWindowService, commonHelper, reportService, paginationService, $routeParams, $q) {
        let self = this;
        this._super($scope);
        this.$location = $location;
        this.$routeParams = $routeParams;
        this.rulesService = rulesService;
        this.reportService = reportService;
        this.commonHelper = commonHelper;
        this.$scope.modalWindow = modalWindowService;
        this.$scope.paginator = paginationService;
        this.$q = $q;

        this.$scope.editConditions = $location.path().slice('/').includes('edit_conditions');

        this.$scope.instance = "complianceCreateEditController";
        this.$scope.DCA = DCA;

        this.$scope.conditionIds = [];
        this.$scope.savedConditions = {};
        this.$scope.data = {};
        this.$scope.ruleData = {conditionMustBeMet: true};
        this.$scope.rulesList = [];
        this.$scope.show_add_form = true;
        this.$scope.ownReports = false;

        initSaveReportScope(this.$scope, this.commonHelper);

        this.$scope.overwrite = false;

        self.rulesService.getrules().then(data => {
            const cancel = {id: -1, type: 'cancel', name: 'None', disabled: false};
            self.$scope.rulesList = [cancel, ...data.data];
            self.disableSelectedConditions();

            // loads all rules belong to current user in case of edit conditions
            if (this.$scope.editConditions) {
                for (const rule of self.$scope.rulesList) {
                    if (rule.username == userName) {
                        this.$scope.conditionIds.push(rule.id);
                    }
                }
            }
        });

        if (this.$routeParams.editReportId) {
            this.loadReport(this.$routeParams.editReportId);
            this.$scope.reportId = this.$routeParams.editReportId;
        }


        /**
         * if previous path was `compliance/run` (this means that edit button was clicked)
         * then load conditions from session storage
         */
        self.$scope.$on('$routeChangeSuccess', function (event, current, previous) {
            if (
                previous != undefined &&
                previous.$$route.originalPath == '/compliance/run' &&
                sessionStorage.getItem('conditions')
            ) {
                self.$scope.conditionIds = JSON.parse(sessionStorage.getItem('conditions'));
            }
        });

        self.commonHelper._setVIEWVariables(self.$scope);
    },

    defineScope: function () {
        this.$scope.isEmptyObj = this.isEmptyObj.bind(this);
        this.$scope.removeCondition = this.removeCondition.bind(this);
        this.$scope.deleteRuleEntity = this.deleteRuleEntity.bind(this);
        this.$scope.runReport = this.runReport.bind(this);
        this.$scope.saveReport = this.saveReport.bind(this);
        this.$scope.saveReportTitleFn = this.saveReportTitleFn.bind(this);
    },

    defineListeners: function () {
        let self = this;

        self.$scope.$on('saveRule_Success_Event', function (event, data) {
            self.$scope.conditionIds.push(data[0].ruleid);
        });

        self.$scope.$on('select_check_event', function (event, id) {
            self.$scope.conditionIds.push(id);
        });

        self.$scope.$on('cancel_Rule_Event', function () {
            self.$scope.showRuleEdit = false;
        });

        self.$scope.$watch('conditionIds', function (newVal, oldVal) {
            self.$scope.savedConditions = {};
            if (self.$scope.conditionIds.length > 0) {
                self.loadConditions();
            }
            self.disableSelectedConditions();

            if (self.$scope.reportId != undefined &&
                self.$scope.reportId > 0 &&
                newVal != oldVal &&
                !_.isEqual(newVal, self.$scope.reportConditions)) {
                self.$scope.reportConditions = angular.copy(newVal);
                self.saveReport(false, null);
            }
        }, true);

        self.$scope.$watch('ruleData', function (rule) {
            if (rule.id != undefined && rule.id > 0) {
                self.$scope.conditionIds.push(rule.id);
                self.$scope.ruleData = {};
            }
        })
    },

    loadConditions: function () {
        this.$scope.show_add_form = false;
        this.$scope.showRuleEdit = false;
        loadConditions(this.$scope, this.rulesService, this.commonHelper)
    },

    saveReportTitleFn: async function () {
        const deferred = this.$q.defer();
        try {
            this.$scope.savedSearchName.input = this.$scope.data.reportLabel;
            await this.saveReport(false, null);
            deferred.resolve();
        } catch (e) {
            deferred.reject(e)
        }

        return deferred.promise;
    },

    disableSelectedConditions: function () {
        let self = this;
        self.$scope.rulesList.forEach((item, index) => {
            self.$scope.rulesList[index].disabled = self.$scope.conditionIds.indexOf(item.id) >= 0 ? true : false;
        });
        $("#rules_dropdown").trigger("chosen:updated");
        setTimeout(function () {
            $("#rules_dropdown").trigger("chosen:updated")
        }, 1000);

    },

    runReport: function () {
        if (this.$scope.reportId) {
            this.$location.path(`compliance/run/${this.$scope.reportId}`);
        } else {
            sessionStorage.setItem('conditions', JSON.stringify(this.$scope.conditionIds));
            this.$location.path(`compliance/run`);
        }
    },

    loadReport: function (id) {
        let self = this;
        self.reportService.loadReport(this.$routeParams.editReportId).then(
            function (result) {
                let data = result.data;
                let reportData = angular.fromJson(data['AdvancedReportsData']);
                self.$scope.overwrite = true;

                if (reportData?.SQL !== undefined) {
                    self.$scope.SQL = angular.fromJson(reportData.SQL);
                    self.$scope.conditionIds = self.$scope.SQL.conditions;
                    self.$scope.reportConditions = angular.copy(self.$scope.SQL.conditions);
                }
                self.$scope.reportLabel = data.label;
                self.$scope.data.reportLabel = data.label;
                self.$scope.savedSearchName.input = data.label;
                self.$scope.reportId = id;
                self.$scope.can_edit = data.can_edit;
                self.$scope.is_public.input = Boolean(data.is_public);

                self.$scope.reportRolesTMP = (data.sharedPermission !== undefined ? angular.fromJson(data.sharedPermission) : {});
                angular.forEach(self.$scope.reportRolesTMP, function (key) {
                    self.$scope.reportRoles[key] = true;
                });
            });
    },
    isEmptyObj: function (obj) {
        return angular.equals({}, obj);
    },
    removeCondition: function (id) {
        let index = this.$scope.conditionIds.indexOf(id);
        if (index != undefined) {
            this.$scope.conditionIds.splice(index, 1);
        }
    },
    deleteRuleEntity: function (id) {
        let self = this;
        $("<div></div>")
            .dialog_modal({
                passedArgs: ["Are you sure you want to remove this condition?", [
                    {
                        "label": "Cancel",
                        "class": "btn-large"
                    },
                    {
                        "label": "Remove",
                        "class": "btn-large btn-primary btn-danger",
                        "callback": function () {
                            self.rulesService.deleterule(id).then(
                                function () {
                                    self.removeCondition(id);
                                    common.globalSpinner.hide();
                                },
                                function (error) {
                                    notify.error(error.data);
                                });
                        }
                    }
                ],
                    {
                        header: "<h2>Remove condition?</h2>"
                    }],
            });
    },
    saveReport: function (...args) {
        const callerPageAction = args[1] !== undefined ? args[1] : 'compliance';
        const uniqueConditions = Array.from(new Set(this.$scope.conditionIds));
        this.$scope.SQL = {conditions: uniqueConditions, SQLSTRING: ""};
        $('.reportSavedText').delay(200).fadeIn(400).delay(1500).fadeOut(300);
        return this.commonHelper.saveReport(this.$scope.overwrite, this.$scope, callerPageAction);
    }
});

complianceCreateEditController.$inject = ['$scope', '$location', 'rulesService', 'modalWindowService', 'commonHelper', 'reportService', 'paginationService', '$routeParams', '$q'];


const complianceResultController = BaseController.extend({

    init: function ($scope, $routeParams, reportService, rulesService, complianceHelper, $q, modalWindowService, commonHelper, inventoryFilterService, inventoryDataService) {
        this._super($scope);
        this.$routeParams = $routeParams;
        this.reportService = reportService;
        this.rulesService = rulesService;
        this.complianceHelper = complianceHelper;
        this.commonHelper = commonHelper;
        this._inventoryFilterService = inventoryFilterService;
        this._inventoryDataService = inventoryDataService;
        this.$scope.complianceHelper = complianceHelper;
        this.$scope.modalWindow = modalWindowService;
        this.$q = $q;

        this.$scope.instance = "complianceController";
        this.$scope.savedConditions = {};
        this.$scope.conditionIds = [];
        this.params = {};
        this.$scope.SQL = {};
        this.$scope.filterData = {};
        this.$scope.filterData.filters = [];
        this.$scope.filterData.entriesFilter = {includes: {}, excludes: {}};
        this.$scope.UI = {};
        this.$scope.alertData = {};
        this.$scope.reportRoles = {};

        this.$scope.CFE_Mapping_addFields = CFE_Mapping_addFields;
        this.$scope.CFE_Mapping_removeFields = CFE_Mapping_removeFields;
        this.$scope.CFE_Mapping_addToFilters = CFE_Mapping_addToFilters;

        this.$scope.hostcontexts = {};
        this.$scope.excludedHosts = '';
        this.$scope.showEnvironmentFilterButtons = true;
        this.timeout = null;

        this.$scope.sortByProperty = '';
        this.$scope.sortMode = 'NOR';

        this.$scope.stats = {
            severity: {
                high: {pass: 0, fail: 0},
                medium: {pass: 0, fail: 0},
                low: {pass: 0, fail: 0}
            },
            categories: {},
            total: {pass: 0, fail: 0},
            totalChecks: 0
        };

        initSaveReportScope(this.$scope, commonHelper);
        this.$scope.overwrite = false;

        this.reportService.getTotalHostsCount(this.getInclExclParams()).then(count => this.$scope.total = count);
        this.runReport();
    },
    sortConditionBy: function (sortProperty) {
        let self = this;
        const shiftMode = () => {
            const modes = ['NOR', 'ASC', 'DSC'];
            const currentModeIndex = modes.findIndex(el => el === self.$scope.sortMode);
            self.$scope.sortMode = (sortProperty === self.$scope.sortByProperty) ? modes[(currentModeIndex + 1) % modes.length] : modes[1];
        }
        shiftMode();
        if (self.$scope.sortMode === 'NOR') {
            groupConditionsByCategory(self.$scope, self.$scope.savedConditions, self.commonHelper)
            return;
        }
        function sortByProperty(array, prop, reverse) {
            const severityOrder = {"high": 3, "medium": 2, "low": 1};
                return array.sort((a, b) => {
                    a = prop === 'severity' ? severityOrder[a[prop]]: a[prop];
                    b = prop === 'severity' ?  severityOrder[b[prop]]: b[prop];
                    if (a < b) {
                        return reverse ? 1 : -1;
                    } else if (a > b) {
                        return reverse ? -1 : 1;
                    }
                    return 0;
                });
        }
        self.$scope.sortByProperty = sortProperty;
        const newConditions = Object.values(self.$scope.savedConditions).flat();
        self.$scope.savedConditions = {All: sortByProperty(newConditions, self.$scope.sortByProperty, self.$scope.sortMode === 'DSC')};
    },
    defineScope: function () {
        this.$scope.loadStatistics = this.loadStatistics.bind(this);
        this.$scope.viewHosts = this.viewHosts.bind(this);
        this.$scope.saveReport = this.saveReport.bind(this);
        this.$scope.sortConditionBy = this.sortConditionBy.bind(this);
    },

    defineListeners: function () {
        let self = this;

        self.$scope.$watch('conditionIds', function () {
            loadConditions(self.$scope, self.rulesService, self.commonHelper);
        }, true);

        $(document).on('exportModal', function () {

            // options to show white theme charts on exported PDFs
            const whiteStyles = {
                chart: {backgroundColor: '#FFF'},
                title: {
                    style: {"color": '#333333', "fontSize": "15px", "fontWeight": "bold"},
                },
                plotOptions: {
                    pie: {
                        dataLabels: {color: '#333333'}
                    }
                }
            };

            // change x and y axis text color for category bar chart
            let categoryOptions = angular.copy($('#category_failures').highcharts().userOptions);
            categoryOptions.xAxis.labels = categoryOptions.yAxis.labels = {style: {color: '#333333'}};
            categoryOptions.xAxis = [categoryOptions.xAxis];
            categoryOptions.yAxis = [categoryOptions.yAxis];

            self.setExportData({
                totalHosts: self.$scope.total,
                reportId: self.$scope.reportId,
                stats: self.$scope.stats,
                savedConditions: self.$scope.savedConditions,
                conditionIds: self.$scope.conditionIds,
                charts: {
                    'overall': $('#overall').highcharts().getSVG(whiteStyles),
                    'categories': $('#category_failures').highcharts().getSVG(Object.assign(categoryOptions, whiteStyles))
                }
            });
        });

        self.$scope.$watch('savedConditions', function () {
            self.buildCsvArray();
        }, true);

        $('body').on('DARK_THEME_CHANGED', function () {
            self.loadCharts();
            self.$scope.$digest();
        });

        self.$scope.$watch('stats', function () {
            self.loadCharts();
            // update compliance score if report id exists, compliance data exist and no hosts filter applied
            if (self.$routeParams.reportid &&
                (self.$scope.stats.total.fail > 0 || self.$scope.stats.total.pass > 0) &&
                (self.getInclExclParams().includes.length == 0 && self.getInclExclParams().excludes.length == 0)
            ) {
                self.reportService.updateComplianceScore({
                    'report_id': self.$routeParams.reportid,
                    'score': self.complianceHelper.getComplianceScore(self.$scope.stats.total.passedHosts, self.$scope.stats.total.hosts),
                    'fail_checks': self.$scope.stats.total.fail,
                    'total': self.$scope.stats.totalChecks,
                });
            }
        }, true);

        self.$scope.$watch(
            function ($scope) {
                return Object.keys($scope.savedConditions).length;
            },
            function () {
                if (Object.keys(self.$scope.savedConditions).length > 0) {
                    self.$scope.loadStatistics();
                }
            }
        );

        setupFilterTreeClickOutside(self.$scope);
    },

    loadCharts: function () {
        this.$scope.overallConfig = this.complianceHelper.overallConfig(this.$scope.stats);
        this.$scope.categoriesConfig = this.complianceHelper.categoriesConfig(this.$scope.stats);
    },

    viewHosts: function (conditionId) {
        this.$location.path(`compliance/run/${this.$scope.reportId}`);
    },
    runReport: function () {
        if (this.$routeParams.reportid) {
            this.loadReport(this.$routeParams.reportid);
            this.$scope.reportid = this.$routeParams.reportid;
        } else if (sessionStorage.getItem('conditions')) {
            this.$scope.conditionIds = JSON.parse(sessionStorage.getItem('conditions'));
        } else {
            notify.error('Report does not exist.');
        }
    },

    loadReport: function (reportid) {
        let self = this;
        let $scope = self.$scope;
        self.reportService.loadReport(reportid).then(
            function (result) {
                let data = result.data;
                let reportData = angular.fromJson(data['AdvancedReportsData']);

                if (reportData?.SQL !== undefined) {
                    angular.extend($scope.SQL, angular.fromJson(reportData.SQL));
                    $scope.SQL.filters = $scope.filterData.filters || [];
                    $scope.SQL.entriesFilter = $scope.filterData.entriesFilter || {includes: {}, excludes: {}};
                    $scope.conditionIds = $scope.SQL.conditions;
                }

                $scope.reportLabel = data.label;
                $scope.reportId = reportid;

                $scope.can_edit = data.can_edit;
                $scope.can_subscribe = data.can_subscribe;
                $scope.can_delete = data.can_delete;
                $scope.is_own = data.is_own;
                $scope.readonly = data.readonly;
                $scope.is_public = {};
                $scope.is_public.input = Boolean(data.is_public);
                $scope.loadedSearch = true;
                $scope.reportRolesTMP = (data.sharedPermission !== undefined ? angular.fromJson(data.sharedPermission) : {});

                angular.forEach($scope.reportRolesTMP, function (key) {
                    $scope.reportRoles[key] = true;
                });
            },
            function (error) {
                notify.error('Unable to load report: ' + error.data);
            });
    },

    loadStatistics: function () {
        let self = this;
        if (this.timeout == null) {
            this.timeout = setTimeout(function () {
                self._loadStatistics()
                self.timeout = null;
            }, 1000);
        }
    },

    _loadStatistics: async function () {
        let self = this;
        let stats = {
            severity: {
                high: {pass: 0, fail: 0},
                medium: {pass: 0, fail: 0},
                low: {pass: 0, fail: 0}
            },
            categories: {},
            total: {pass: 0, fail: 0, hosts: 0, passedHosts: 0, totalHosts: 0},
            totalChecks: 0,
            totalHosts: self.$scope.total
        };

         const params = {
            filter: self._inventoryFilterService.processFilters(self.$scope.filterData.filters),
            hostFilter: self._inventoryFilterService.processEntriesFilters(self.$scope.filterData),
            hostContextInclude: self._inventoryFilterService.processClassFilters(self.$scope.filterData.filters),
            hostContextExclude: [],
        };

        let ids = [];
        stats.totalChecks = self.$scope.conditionIds.length;
        
        const ruleIds = Object.keys(self.$scope.savedConditions).reduce((acc, category) => {
            acc = [...acc, ...self.$scope.savedConditions[category].map(item => item.id)];
            return acc;
        }, []);

        const {data: statistics} = await  self.rulesService.getAllStats(ruleIds, params);

        for (const category in self.$scope.savedConditions) {

            if (stats.categories[category] == undefined) {
                stats.categories[category] = {totalPassedHosts: 0, totalHosts: 0};
            }

            self.$scope.savedConditions[category] = self.$scope.savedConditions[category].map(item => {
                const { failHosts = 0, total = 0 } = Object.values(statistics).find(v => v.ruleId === item.id);
                item.total = total;
                item.fail = failHosts;
                item.pass = item.total - failHosts;
                item.score = self.complianceHelper.getComplianceScore(item.pass, item.total);

                // set score 100 when 0 hosts (failing is 0 as well), happens when rbac filter applied
                if (item.total === 0) {
                    item.score = 100;
                }

                stats.categories[category].totalPassedHosts += item.pass;
                stats.categories[category].totalHosts += item.total;

                if (item.severity) {
                    stats.severity[item.severity]['fail'] += item.fail > 0 ? 1 : 0;
                    stats.severity[item.severity]['pass'] += item.fail === 0 ? 1 : 0;
                }

                stats.total.fail += item.fail > 0 ? 1 : 0;
                stats.total.pass += item.fail === 0 ? 1 : 0;
                stats.total.passedHosts += item.pass;
                stats.total.hosts += item.total;

                return item;
            });
        }
        self.$scope.stats = stats;
        self.$scope.$apply();
    },

    getInclExclParams: function () {
        return {
            includes: (this.$scope.SQL.hostcontexts !== undefined && this.$scope.SQL.hostcontexts.includes !== undefined) ?
                this.$scope.SQL.hostcontexts.includes :
                [],
            excludes: (this.$scope.SQL.excludedHosts !== undefined && this.$scope.SQL.excludedHosts.excludes !== undefined) ?
                this.$scope.SQL.excludedHosts.excludes :
                []
        }
    },

    saveReport: function () {
        this.$scope.SQL = {conditions: this.$scope.conditionIds, SQLSTRING: ""};
        this.commonHelper.saveReport(this.$scope.overwrite, this.$scope, 'compliance');
    },

    setExportData: function (obj) {
        $('#compliance_data').val(JSON.stringify(obj));
    },

    buildCsvArray: function () {
        let self = this;
        let csvArray = [[
            'Name', 'Severity level', 'Compliance score', 'Category', 'Passing', 'All'
        ]];
        Object.keys(this.$scope.savedConditions).forEach(category => {
            this.$scope.savedConditions[category].forEach(condition => {
                csvArray.push([
                    condition.name,
                    condition.severity,
                    condition.score,
                    category,
                    condition.pass,
                    condition.total,
                ])
            })
        });
        $('#csvArray').val(JSON.stringify(csvArray));
    }
});

complianceResultController.$inject = ['$scope', '$routeParams', 'reportService', 'rulesService', 'complianceHelper', '$q', 'modalWindowService', 'commonHelper', 'inventoryFilterService', 'inventoryDataService'];


const complianceImportController = BaseController.extend({

    init: function ($scope, rulesService, reportService) {
        let self = this;
        this._super($scope);
        this.rulesService = rulesService;
        this.reportService = reportService;
        this.$scope.instance = "complianceImportController";
        this.$scope.import = {reports: {}, conditions: {}};
    },

    defineScope: function () {
        this.$scope.clearData = this.clearData.bind(this);
        this.$scope.importReport = this.importReport.bind(this);
    },

    clearData: function () {
        this.$scope.import = {reports: {}, conditions: {}};
    },

    importReport: function (overwrite = false) {
        common.globalSpinner.show();
        let self = this;
        this.reportService.importComplianceReport(JSON.stringify(this.$scope.import.content), overwrite).then(
            () => {
                common.globalSpinner.hide();
                self.clearData();
                notify.success('Report successfully imported.');
            },
            (error) => {
                notify.error(`Error occurred while importing: ${error.data}`);
                if (error.data.duplicates) {
                    self.$scope.import.duplicates = error.data.duplicates;
                }
                common.globalSpinner.hide();
            }
        );
    },

    defineListeners: function () {
        let self = this;

        self.$scope.$on('FILE_SELECTED', (event, data) => {
            self.clearData();
            try {
                self.$scope.import.content = JSON.parse(data.content);
            } catch ($e) {
                notify.error('Wrong JSON format.');
                return;
            }

            self.$scope.import.fileName = data.name;
            const content = self.$scope.import.content;
            if (!content.hasOwnProperty('reports')) {
                notify.error("Wrong JSON format, reports are missing.");
                return;
            }
            self.$scope.$apply();
        })

        self.$scope.$watch('import.content', content => {
            if (!content) {
                return;
            }
            const reports = content.reports;
            let reportConditions = [];
            Object.keys(content.reports).forEach(id => {
                const report = reports[id];
                self.$scope.import.reports[report.title] = false;
                reportConditions = [...reportConditions, ...report['conditions']];
                self.reportService.getReportByExportId(report.id).then(() => {
                    self.$scope.import.reports[report.title] = true;
                    self.$scope.overwrite = true;
                });
            })

            const filteredConditions = Object.keys(content.conditions).filter((cond) => reportConditions.includes(cond));
            self.rulesService.getRulesByExportIds(
                filteredConditions.map(id => {
                    const condition = content.conditions[id];
                    self.$scope.import.conditions[condition.name] = false;
                    return condition.id;
                })
            ).then((response) => {
                for (const condition of response.data) {
                    self.$scope.import.conditions[condition.name] = true;
                }
                self.$scope.overwrite = true;
            });
        });
    }
});

complianceImportController.$inject = ['$scope', 'rulesService', 'reportService'];

