/*
 * 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.
 */

'use strict';

const _ = require('lodash');

// Fire me up!

module.exports = {
    implements: 'services/notebooks',
    inject: ['mongo', 'services/spaces', 'errors']
};

/**
 * @param mongo
 * @param {SpacesService} spacesService
 * @param errors
 * @returns {NotebooksService}
 */
module.exports.factory = (mongo, spacesService, errors) => {
    /**
     * Convert remove status operation to own presentation.
     *
     * @param {RemoveResult} result - The results of remove operation.
     */
    const convertRemoveStatus = (result) => ({rowsAffected: result.n});

    /**
     * Update existing notebook.
     *
     * @param {Object} notebook - The notebook for updating
     * @returns {Promise.<mongo.ObjectId>} that resolves cache id
     */
    const update = (notebook) => {
        return mongo.Notebook.findOneAndUpdate({_id: notebook._id}, notebook, {new: true, upsert: true}).exec()
            .catch((err) => {
                if (err.code === mongo.errCodes.DUPLICATE_KEY_UPDATE_ERROR || err.code === mongo.errCodes.DUPLICATE_KEY_ERROR)
                    throw new errors.DuplicateKeyException('Notebook with name: "' + notebook.name + '" already exist.');
                else
                    throw err;
            });
    };

    /**
     * Create new notebook.
     *
     * @param {Object} notebook - The notebook for creation.
     * @returns {Promise.<mongo.ObjectId>} that resolves cache id.
     */
    const create = (notebook) => {
        return mongo.Notebook.create(notebook)
            .catch((err) => {
                if (err.code === mongo.errCodes.DUPLICATE_KEY_ERROR)
                    throw new errors.DuplicateKeyException('Notebook with name: "' + notebook.name + '" already exist.');
                else
                    throw err;
            });
    };

    class NotebooksService {
        /**
         * Create or update Notebook.
         *
         * @param {Object} notebook - The Notebook
         * @returns {Promise.<mongo.ObjectId>} that resolves Notebook id of merge operation.
         */
        static merge(notebook) {
            if (notebook._id)
                return update(notebook);

            return create(notebook);
        }

        /**
         * Get notebooks by spaces.
         *
         * @param {mongo.ObjectId|String} spaceIds - The spaces ids that own caches.
         * @returns {Promise.<mongo.Notebook[]>} - contains requested caches.
         */
        static listBySpaces(spaceIds) {
            return mongo.Notebook.find({space: {$in: spaceIds}}).sort('name').lean().exec();
        }

        /**
         * Remove notebook.
         *
         * @param {mongo.ObjectId|String} notebookId - The Notebook id for remove.
         * @returns {Promise.<{rowsAffected}>} - The number of affected rows.
         */
        static remove(notebookId) {
            if (_.isNil(notebookId))
                return Promise.reject(new errors.IllegalArgumentException('Notebook id can not be undefined or null'));

            return mongo.Notebook.deleteOne({_id: notebookId}).exec()
                .then(convertRemoveStatus);
        }
    }

    return NotebooksService;
};
