/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

import NfStorage from 'services/nf-storage.service';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { FdsDialogService } from '@flow-design-system/dialogs';
import { Observable } from 'rxjs';

var MILLIS_PER_SECOND = 1000;
var headers = new Headers({'Content-Type': 'application/json'});

var config = {
    urls: {
        currentUser: '/nifi-registry-api/access',
        kerberos: '/nifi-registry-api/access/token/kerberos'
    }
};

/**
 * NfRegistryApi constructor.
 *
 * @param nfStorage             A wrapper for the browser's local storage.
 * @param http                  The angular http module.
 * @param fdsDialogService      The FDS dialog service.
 * @constructor
 */
function NfRegistryApi(nfStorage, http, fdsDialogService) {
    this.nfStorage = nfStorage;
    this.http = http;
    this.dialogService = fdsDialogService;
}

NfRegistryApi.prototype = {
    constructor: NfRegistryApi,

    /**
     * Retrieves the snapshot metadata for an existing droplet the registry has stored.
     *
     * @param {string}  dropletUri     The uri of the droplet to request.
     * @returns {*}
     */
    getDropletSnapshotMetadata: function (dropletUri) {
        var self = this;
        var url = '/nifi-registry-api/' + dropletUri;
        url += '/versions';
        return this.http.get(url)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                self.dialogService.openConfirm({
                    title: 'Error',
                    message: error.error,
                    acceptButton: 'Ok',
                    acceptButtonColor: 'fds-warn'
                });
                return Observable.of(error);
            });
    },

    /**
     * Retrieves the given droplet with or without snapshot metadata.
     *
     * @param {string}  bucketId        The id of the bucket to request.
     * @param {string}  dropletType     The type of the droplet to request.
     * @param {string}  dropletId       The id of the droplet to request.
     * @returns {*}
     */
    getDroplet: function (bucketId, dropletType, dropletId) {
        var self = this;
        var url = '/nifi-registry-api/buckets/' + bucketId + '/' + dropletType + '/' + dropletId;
        return this.http.get(url)
            .map(function (response) {
                return response || {};
            })
            .catch(function (error) {
                self.dialogService.openConfirm({
                    title: 'Flow Not Found',
                    message: error.error,
                    acceptButton: 'Ok',
                    acceptButtonColor: 'fds-warn'
                });
                return Observable.of(error);
            });
    },

    /**
     * Retrieves all droplets across all buckets (unless the `bucketId` is set then this will
     * retrieve all droplets across that specific bucket). Droplets could include flows, extensions, etc.
     *
     * No snapshot metadata ever returned.
     *
     * @param {string} [bucketId] Defines a bucket id for filtering results.
     * @returns {*}
     */
    getDroplets: function (bucketId) {
        var url = '/nifi-registry-api/items';
        if (bucketId) {
            url += '/' + bucketId;
        }
        return this.http.get(url)
            .map(function (response) {
                return response || [];
            })
            .catch(function (error) {
                return Observable.of(error);
            });
    },

    /**
     * Delete an existing droplet the registry has stored.
     *
     * @param {string} dropletUri    The portion of the URI describing the type of the droplet and its identifier
     *
     *  Ex:
     *      'flows/1234'
     *      'extension/5678'
     *
     * @returns {*}
     */
    deleteDroplet: function (dropletUri) {
        var self = this;
        return this.http.delete('/nifi-registry-api/' + dropletUri, headers)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                self.dialogService.openConfirm({
                    title: 'Error',
                    message: error.error,
                    acceptButton: 'Ok',
                    acceptButtonColor: 'fds-warn'
                });
                return Observable.of(error);
            });
    },

    /**
     * Create a named bucket capable of storing NiFi bucket objects (aka droplets) such as flows and extension bundles.
     *
     * @param {string} name  The name of the bucket.
     * @returns {*}
     */
    createBucket: function (name) {
        var self = this;
        return this.http.post('/nifi-registry-api/buckets', {'name': name}, headers)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                self.dialogService.openConfirm({
                    title: 'Error',
                    message: error.error,
                    acceptButton: 'Ok',
                    acceptButtonColor: 'fds-warn'
                });
                return Observable.of(error);
            });
    },

    /**
     * Delete an existing bucket in the registry, along with all the objects it is storing.
     *
     * @param {string} bucketId     The identifier of the bucket to be deleted.
     * @returns {*}
     */
    deleteBucket: function (bucketId) {
        var self = this;
        return this.http.delete('/nifi-registry-api/buckets/' + bucketId, headers)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                self.dialogService.openConfirm({
                    title: 'Error',
                    message: error.error,
                    acceptButton: 'Ok',
                    acceptButtonColor: 'fds-warn'
                });
                return Observable.of(error);
            });
    },

    /**
     * Get metadata for an existing bucket in the registry.
     *
     * @param {string} bucketId     The identifier of the bucket to retrieve.
     * @returns {*}
     */
    getBucket: function (bucketId) {
        var self = this;
        var url = '/nifi-registry-api/buckets/' + bucketId;
        return this.http.get(url)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                self.dialogService.openConfirm({
                    title: 'Bucket Not Found',
                    message: error.error,
                    acceptButton: 'Ok',
                    acceptButtonColor: 'fds-warn'
                });
                return Observable.of(error);
            });
    },

    /**
     * Get metadata for all buckets in the registry for which the client is authorized.
     *
     * NOTE: Information about the items stored in each bucket should be obtained by
     * requesting and individual bucket by id.
     *
     * @returns {*}
     */
    getBuckets: function () {
        var self = this;
        var url = '/nifi-registry-api/buckets';
        return this.http.get(url)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                self.dialogService.openConfirm({
                    title: 'Buckets Not Found',
                    message: error.error,
                    acceptButton: 'Ok',
                    acceptButtonColor: 'fds-warn'
                });
                return Observable.of(error);
            });
    },

    /**
     * Updates a bucket.
     *
     * @param {Object} updatedBucket           Object containing The identifier and name of the bucket as well as Whether or not the bucket allows redeploying released bundles.
     * @returns {*}
     */
    updateBucket: function (updatedBucket) {
        return this.http.put('/nifi-registry-api/buckets/' + updatedBucket.identifier, updatedBucket, headers)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                return Observable.of(error);
            });
    },

    /**
     * Get user by id.
     *
     * @param userId
     * @returns {*}
     */
    getUser: function (userId) {
        var self = this;
        return this.http.get('/nifi-registry-api/tenants/users/' + userId)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                self.dialogService.openConfirm({
                    title: 'User Not Found',
                    message: error.error,
                    acceptButton: 'Ok',
                    acceptButtonColor: 'fds-warn'
                });
                return Observable.of(error);
            });
    },

    /**
     * Creates a user.
     *
     * @param {string} identity     The identity of the user.
     * @returns {*}
     */
    addUser: function (identity) {
        var self = this;
        return this.http.post('/nifi-registry-api/tenants/users', {
            identity: identity,
            resourcePermissions: {
                anyTopLevelResource: {
                    canRead: false,
                    canWrite: false,
                    canDelete: false
                },
                buckets: {
                    canRead: false,
                    canWrite: false,
                    canDelete: false
                },
                tenants: {
                    canRead: false,
                    canWrite: false,
                    canDelete: false
                },
                policies: {
                    canRead: false,
                    canWrite: false,
                    canDelete: false
                },
                proxy: {
                    canRead: false,
                    canWrite: false,
                    canDelete: false
                }
            }
        }, headers)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                self.dialogService.openConfirm({
                    title: 'Error',
                    message: error.error,
                    acceptButton: 'Ok',
                    acceptButtonColor: 'fds-warn'
                });
                return Observable.of(error);
            });
    },

    /**
     * Updates a user.
     *
     * @param {string} identifier   The identifier of the user.
     * @param {string} identity     The identity of the user.
     * @returns {*}
     */
    updateUser: function (identifier, identity) {
        return this.http.put('/nifi-registry-api/tenants/users/' + identifier, {
            'identifier': identifier,
            'identity': identity
        }, headers)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                return Observable.of(error);
            });
    },

    /**
     * Gets all users.
     *
     * @returns {*}
     */
    getUsers: function () {
        var self = this;
        return this.http.get('/nifi-registry-api/tenants/users')
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                self.dialogService.openConfirm({
                    title: 'Users Not Found',
                    message: error.error,
                    acceptButton: 'Ok',
                    acceptButtonColor: 'fds-warn'
                });
                return Observable.of(error);
            });
    },

    /**
     * Delete an existing user from the registry.
     *
     * @param {string} userId     The identifier of the user to be deleted.
     * @returns {*}
     */
    deleteUser: function (userId) {
        var self = this;
        return this.http.delete('/nifi-registry-api/tenants/users/' + userId, headers)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                self.dialogService.openConfirm({
                    title: 'Error',
                    message: error.error,
                    acceptButton: 'Ok',
                    acceptButtonColor: 'fds-warn'
                });
                return Observable.of(error);
            });
    },

    /**
     * Gets all user groups.
     *
     * @returns {*}
     */
    getUserGroups: function () {
        var self = this;
        return this.http.get('/nifi-registry-api/tenants/user-groups')
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                self.dialogService.openConfirm({
                    title: 'Groups Not Found',
                    message: error.error,
                    acceptButton: 'Ok',
                    acceptButtonColor: 'fds-warn'
                });
                return Observable.of(error);
            });
    },

    /**
     * Get user group.
     *
     * @param {string} groupId  The id of the group to retrieve.
     * @returns {*}
     */
    getUserGroup: function (groupId) {
        var self = this;
        return this.http.get('/nifi-registry-api/tenants/user-groups/' + groupId)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                self.dialogService.openConfirm({
                    title: 'Group Not Found',
                    message: error.error,
                    acceptButton: 'Ok',
                    acceptButtonColor: 'fds-warn'
                });
                return Observable.of(error);
            });
    },

    /**
     * Delete an existing user group from the registry.
     *
     * @param {string} userGroupId     The identifier of the user group to be deleted.
     * @returns {*}
     */
    deleteUserGroup: function (userGroupId) {
        var self = this;
        return this.http.delete('/nifi-registry-api/tenants/user-groups/' + userGroupId, headers)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                self.dialogService.openConfirm({
                    title: 'Error',
                    message: error.error,
                    acceptButton: 'Ok',
                    acceptButtonColor: 'fds-warn'
                });
                return Observable.of(error);
            });
    },

    /**
     * Creates a new group.
     *
     * @param {string}  identifier      The identifier of the user.
     * @param {string}  identity        The identity of the user.
     * @param {array}   users           The array of users to be added to the new group.
     * @returns {*}
     */
    createNewGroup: function (identifier, identity, users) {
        var self = this;
        return this.http.post('/nifi-registry-api/tenants/user-groups', {
            'identifier': identifier,
            'identity': identity,
            'users': users
        }, headers)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                self.dialogService.openConfirm({
                    title: 'Error',
                    message: error.error,
                    acceptButton: 'Ok',
                    acceptButtonColor: 'fds-warn'
                });
                return Observable.of(error);
            });
    },

    /**
     * Updates a group.
     *
     * @param {string}  identifier   The identifier of the group.
     * @param {string}  identity     The identity of the group.
     * @param {array}   users         The array of users in the new group.
     * @returns {*}
     */
    updateUserGroup: function (identifier, identity, users) {
        return this.http.put('/nifi-registry-api/tenants/user-groups/' + identifier, {
            'identifier': identifier,
            'identity': identity,
            'users': users
        }, headers)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                return Observable.of(error);
            });
    },

    /**
     * Get metadata for all policies in the registry for which the client is authorized.
     *
     * @returns {*}
     */
    getPolicies: function () {
        var url = '/nifi-registry-api/policies';
        return this.http.get(url)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                return Observable.of(error);
            });
    },

    /**
     * Get resource policies by resource identifier.
     *
     * @param {string} action       The name of the resource action (e.g. READ/WRITE/DELETE).
     * @param {string} resource     The name of the resource (e.g. /buckets, /tenants, /policies, /proxy).
     * @param {string} resourceId   The resource identifier.
     * @returns {*}
     */
    getResourcePoliciesById: function (action, resource, resourceId) {
        return this.http.get('/nifi-registry-api/policies/' + action + resource + '/' + resourceId)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                return Observable.of(error);
            });
    },

    /**
     * Get policy action resource.
     *
     * @param {string} action   The name of the resource action (e.g. READ/WRITE/DELETE).
     * @param {string} resource     The name of the resource (e.g. /buckets, /tenants, /policies, /proxy).
     * @returns {*}
     */
    getPolicyActionResource: function (action, resource) {
        return this.http.get('/nifi-registry-api/policies/' + action + resource)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                return Observable.of(error);
            });
    },

    /**
     * Update policy action resource.
     *
     * @param {string} identifier   The identifier of the group.
     * @param {string} action       The name of the resource action (e.g. READ/WRITE/DELETE).
     * @param {string} resource     The name of the resource (e.g. /buckets, /tenants, /policies, /proxy).
     * @param {string} users        The users with resource privileges.
     * @param {string} userGroups   The user groups with resource privileges.
     * @returns {*}
     */
    putPolicyActionResource: function (identifier, action, resource, users, userGroups) {
        var self = this;
        return this.http.put('/nifi-registry-api/policies/' + identifier, {
            'identifier': identifier,
            'resource': resource,
            'action': action,
            'users': users,
            'userGroups': userGroups
        }, headers)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                self.dialogService.openConfirm({
                    title: 'Error',
                    message: error.error,
                    acceptButton: 'Ok',
                    acceptButtonColor: 'fds-warn'
                });
                return Observable.of(error);
            });
    },

    /**
     * Creates a policy action resource.
     *
     * @param {string} action       The name of the resource action (e.g. READ/WRITE/DELETE).
     * @param {string} resource     The name of the resource (e.g. /buckets, /tenants, /policies, /proxy).
     * @param {string} users        The users with resource privileges.
     * @param {string} userGroups   The user groups with resource privileges.
     * @returns {*}
     */
    postPolicyActionResource: function (action, resource, users, userGroups) {
        var self = this;
        return this.http.post('/nifi-registry-api/policies', {
            'resource': resource,
            'action': action,
            'users': users,
            'userGroups': userGroups
        }, headers)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                self.dialogService.openConfirm({
                    title: 'Error',
                    message: error.error,
                    acceptButton: 'Ok',
                    acceptButtonColor: 'fds-warn'
                });
                return Observable.of(error);
            });
    },

    /**
     * Authenticate a user.
     *
     * @param {string} username     The name of the user to authenticate.
     * @param {string} password     The user password.
     * @returns {*}
     */
    postToLogin: function (username, password) {
        var self = this;

        var encodedCredentials = btoa(username + ':' + password);
        var headers = new HttpHeaders({
            'Authorization': 'Basic ' + encodedCredentials
        });

        var options = {
            headers: headers,
            withCredentials: true,
            responseType: 'text'
        };
        return this.http.post('/nifi-registry-api/access/token/login', null, options)
            .map(function (jwt) {
                // get the payload and store the token with the appropriate expiration
                var token = self.nfStorage.getJwtPayload(jwt);
                if (token) {
                    var expiration = parseInt(token['exp'], 10) * MILLIS_PER_SECOND;
                    self.nfStorage.setItem('jwt', jwt, expiration);
                }
                return jwt;
            })
            .catch(function (error) {
                self.dialogService.openConfirm({
                    title: 'Error',
                    message: 'Please contact your System Administrator.',
                    acceptButton: 'Ok',
                    acceptButtonColor: 'fds-warn'
                });
                return Observable.of('');
            });
    },

    /**
     * Kerberos ticket exchange.
     *
     * @returns {*}
     */
    ticketExchange: function () {
        var self = this;
        if (this.nfStorage.hasItem('jwt')) {
            return Observable.of(self.nfStorage.getItem('jwt'));
        }
        return this.http.post(config.urls.kerberos, null, {responseType: 'text'})
            .map(function (jwt) {
                // get the payload and store the token with the appropriate expiration
                var token = self.nfStorage.getJwtPayload(jwt);
                if (token) {
                    var expiration = parseInt(token['exp'], 10) * MILLIS_PER_SECOND;
                    self.nfStorage.setItem('jwt', jwt, expiration);
                }
                return jwt;
            })
            .catch(function (error) {
                return Observable.of('');
            });
    },

    /**
     * Loads the current user and updates the current user locally.
     *
     * @returns xhr
     */
    loadCurrentUser: function () {
        // get the current user
        return this.http.get(config.urls.currentUser)
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                return Observable.of({
                    error: error,
                    resourcePermissions: {
                        anyTopLevelResource: {
                            canRead: false,
                            canWrite: false,
                            canDelete: false
                        },
                        buckets: {
                            canRead: false,
                            canWrite: false,
                            canDelete: false
                        },
                        tenants: {
                            canRead: false,
                            canWrite: false,
                            canDelete: false
                        },
                        policies: {
                            canRead: false,
                            canWrite: false,
                            canDelete: false
                        },
                        proxy: {
                            canRead: false,
                            canWrite: false,
                            canDelete: false
                        }
                    }
                });
            });
    },

    /**
     * Get NiFi Registry configuration resource.
     *
     * @returns {*}
     */
    getRegistryConfig: function (action, resource) {
        return this.http.get('/nifi-registry-api/config')
            .map(function (response) {
                return response;
            })
            .catch(function (error) {
                // If failed, return an empty object.
                return Observable.of({});
            });
    }

};

NfRegistryApi.parameters = [
    NfStorage,
    HttpClient,
    FdsDialogService
];

export default NfRegistryApi;
