/*-
 * #%L
 * thinkbig-ui-feed-manager
 * %%
 * Copyright (C) 2017 ThinkBig Analytics
 * %%
 * 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.
 * #L%
 */
(function () {

    var directive = function () {
        return {
            restrict: "EA",
            bindToController: {},
            controllerAs: 'vm',
            scope: {},
            templateUrl: 'js/feed-details/details/feed-nifi-properties.html',
            controller: "FeedNifiPropertiesController",
            link: function ($scope, element, attrs, controller) {

            }

        };
    }

    var controller = function ($scope, $http,RestUrlService,AccessControlService, FeedService, EditFeedNifiPropertiesService, FeedInputProcessorOptionsFactory, FeedDetailsProcessorRenderingHelper, BroadcastService) {

        var self = this;




        /**
         * Indicates if the feed NiFi properties may be edited.
         * @type {boolean}
         */
        self.allowEdit = false;

        this.model = FeedService.editFeedModel;
        this.editModel = {};
        this.editableSection = false;
        this.INCREMENTAL_DATE_PROPERTY_KEY = 'Date Field';

        $scope.$watch(function () {
            return FeedService.editFeedModel;
        }, function (newVal) {
            //only update the model if it is not set yet
            if (self.model == null) {
                self.model = angular.copy(FeedService.editFeedModel);

            }
            //tell the ui what properties to show/hide
            var renderGetTableData = FeedDetailsProcessorRenderingHelper.updateGetTableDataRendering(self.model.inputProcessor, self.model.nonInputProcessors);
            //   var renderSqoop = FeedDetailsProcessorRenderingHelper.updateSqoopProcessorRendering(self.model.inputProcessor, self.model.nonInputProcessors);
            updateControllerServiceProperties();
        })

        var inputProcessorIdWatch = $scope.$watch(function () {
            return self.editModel.inputProcessorId;
        }, function (newVal) {
            updateInputProcessor(newVal);
            //validate();
        });

        function setInputProcessorFeedPropertiesUrl(processor) {

            if (processor.feedPropertiesUrl == undefined) {
                processor.feedPropertiesUrl = null;
            }
            if (processor.feedPropertiesUrl == null) {
                processor.feedPropertiesUrl = FeedInputProcessorOptionsFactory.templateForProcessor(processor, 'edit');
            }
        }

        function updateInputProcessor(newVal) {
            angular.forEach(self.editModel.inputProcessors, function (processor) {
                if (processor.processorId == newVal) {
                    //check the type and return the custom form if there is one via a factory
                    var renderGetTableData = FeedDetailsProcessorRenderingHelper.updateGetTableDataRendering(processor, self.editModel.nonInputProcessors);
                    //   var renderSqoop = FeedDetailsProcessorRenderingHelper.updateSqoopProcessorRendering(processor, self.editModel.nonInputProcessors);
                    if (renderGetTableData) {
                        self.model.table.method = 'EXISTING_TABLE';
                    }
                    self.editModel.inputProcessor = processor;
                    self.editModel.inputProcessorType = processor.type;
                    //  setInputProcessorFeedPropertiesUrl(processor);
                    return false;
                }
            })
        }

        function findIncrementalDateFieldProperty() {
            return findProperty(self.INCREMENTAL_DATE_PROPERTY_KEY);
        }

        /**
         * add the select options to controller services
         */
        function updateControllerServiceProperties(){

               _.filter(self.model.nonInputProcessors, function (processor) {
                if(processor && processor.properties){
                    var props = _.filter(processor.properties,function(property){
                        if(isControllerServiceProperty(property)){
                            setControllerServicePropertyDisplayName(property);
                        }
                    });
                }
            });

            _.filter(self.model.inputProcessor, function (processor) {
                if(processor && processor.properties){
                    var props = _.filter(processor.properties,function(property){
                        if(isControllerServiceProperty(property)){
                            setControllerServicePropertyDisplayName(property);
                        }
                    });
                }
            });


        }

        /**
         * determine if a property is a controller service
         * @param property
         * @returns {boolean}
         */
        function isControllerServiceProperty(property){
            var controllerService = property.propertyDescriptor.identifiesControllerService;
            if(controllerService != null && controllerService != undefined && controllerService != ''){
                return true;
            }
            return false;
        }

        /**
         * add the proper select values to controller services
         * @param property
         */
        function setControllerServicePropertyDisplayName(property){
         var controllerService = property.propertyDescriptor.identifiesControllerService;
         if(controllerService != null && controllerService != undefined && controllerService != ''){
             //fetch the name
             var promise = $http.get(RestUrlService.GET_CONTROLLER_SERVICE_URL(property.value));
             promise.then(function(response) {
                 if(response && response.data ){
                     property.displayValue = response.data.name;
                     //set the allowable values on the property
                     if(property.propertyDescriptor.allowableValues == null){
                         property.propertyDescriptor.allowableValues = [];
                         property.propertyDescriptor.allowableValues.push({value:property.value,displayName:property.displayValue});
                     }
                 }
             }, function(err){
                 //unable to fetch controller service... the id will display
             });


         }
        }



        function findProperty(key) {
            return _.find(self.model.allProperties, function (property) {
                //return property.key = 'Source Database Connection';
                return property.key == key;
            });
        }

        this.onEdit = function () {
            //copy the model
            var inputProcessors = angular.copy(FeedService.editFeedModel.inputProcessors);
            var nonInputProcessors = angular.copy(FeedService.editFeedModel.nonInputProcessors);
            self.editModel = {};

            var allInputProperties = _.filter(self.model.properties, function (property) {
                return property.inputProperty == true;
            });

            var allInputProcessorProperties = _.groupBy(allInputProperties, function (property) {
                return property.processorId;
            })

            var allInputProcessorProperties = angular.copy(allInputProcessorProperties);
            self.editModel.allInputProcessorProperties = allInputProcessorProperties;
            self.editModel.inputProcessors = inputProcessors;
            self.editModel.nonInputProcessors = nonInputProcessors;
            //NEED TO COPY IN TABLE PROPS HERE
            self.editModel.table = angular.copy(FeedService.editFeedModel.table);
            EditFeedNifiPropertiesService.editFeedModel = self.editModel;
            if (angular.isDefined(self.model.inputProcessor)) {
                updateInputProcessor(self.model.inputProcessor.processorId);
                self.editModel.inputProcessorId = self.model.inputProcessor.processorId;
            }
        };

        this.onCancel = function () {

        }
        this.onSave = function (ev) {
            FeedService.showFeedSavingDialog(ev, "Saving...", self.model.feedName);

            var copy = angular.copy(FeedService.editFeedModel);

            copy.inputProcessors = self.editModel.inputProcessors;
            copy.nonInputProcessors = self.editModel.nonInputProcessors;
            copy.inputProcessorId = self.editModel.inputProcessorId;
            copy.inputProcessor = self.editModel.inputProcessor;
            copy.inputProcessorType = self.editModel.inputProcessorType;
            copy.userProperties = null;

            //table type is edited here so need to update that prop as well
            copy.table.tableType = self.editModel.table.tableType

            if (copy.table.incrementalDateField) {
                var dateProperty = findIncrementalDateFieldProperty();
                if(dateProperty) {
                    dateProperty.value = self.editModel.table.incrementalDateField;
                }
                copy.table.incrementalDateField = self.editModel.table.incrementalDateField;
            }

            //update the db properties

            FeedService.saveFeedModel(copy).then(function (response) {
                FeedService.hideFeedSavingDialog();

                self.editableSection = false;


                self.model.inputProcessors = self.editModel.inputProcessors;
                self.model.nonInputProcessors = self.editModel.nonInputProcessors;
                self.model.inputProcessorId = self.editModel.inputProcessorId;
                self.model.inputProcessor = self.editModel.inputProcessor;
                self.model.table.tableType = self.editModel.table.tableType;
                self.model.table.incrementalDateField = self.editModel.table.incrementalDateField;
                self.model.inputProcessorType = self.editModel.inputProcessorType;

            }, function (response) {
                FeedService.hideFeedSavingDialog();
                console.log('ERRORS were found ', response)
                FeedService.buildErrorData(self.model.feedName, response.data);
                FeedService.showFeedErrorsDialog();
                //make it editable
                self.editableSection = true;
            });
        };

        // Fetch the allowed actions
        AccessControlService.getAllowedActions()
                .then(function(actionSet) {
                    self.allowEdit = AccessControlService.hasAction(AccessControlService.FEEDS_EDIT, actionSet.actions);
                });
    };

    angular.module(MODULE_FEED_MGR).controller('FeedNifiPropertiesController', controller);

    angular.module(MODULE_FEED_MGR)
        .directive('thinkbigFeedNifiProperties', directive);

})();
