/*
 * Notifier Magnifique
 * Copyright 2014 Thiago Uriel M. Garcia
 * https://github.com/ThiagoUriel/notifier-magnifique
 *
 * 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.
 */
"use strict"

const express = require('express');
const router  = express.Router();

const logger = require('../../core/logger').logger; 
const db     = require('../../core/database').client;
const applications = db.collection('applications');

const ApplicationCreated = require('../events/application_created');
const onApplicationCreated = new ApplicationCreated();

const ApplicationUpdated = require('../events/application_updated');
const onApplicationUpdated = new ApplicationUpdated();

const ApplicationDeleted = require('../events/application_deleted');
const onApplicationDeleted = new ApplicationDeleted();

//----[ Routes for "/" URI ]-------------------------------------------------------------

router.route('/')

    /*
     * STORY 01:
     *   As an application developer, I want to list all my applications, regardless of
     *   their current status, so I can gather information (such as their identifiers)
     *   and use it to execute CRUD operations to them. 
     */
    .get(function(req, res, next) 
    {
        const user = req.user;
        const query = {'ownerID': user._id};
        applications.find(query).toArray(function(err, results)
        {
            if (!err)
            {
                if (results && results.length > 0)
                    res.status(200).json(results);
                else
                    res.status(404).end();    
            }
            else
                res.send(500).json(err);
        });
    })

    /*
     * STORY 02:
     *   As an application developer, I want to create an application by providing details,
     *   so a new application is registered to my account.
     * 
     *   Needed details for a new application are: codename (unique among my apps), name,
     *   description, image URL (optional), current status (development or production), 
     *   supported platforms (like GCM, APNS, MPNS, ADM and so on) and contact information 
     *   (also option, but it will consider logged user's information).
     *
     * STORY 03:
     *   As an API developer, I want to be notified whenever an application is created, so
     *   I can act upon this event without the need to change original code, thus keeping
     *   my customization decoupled.
     *
     *   On success, it will emit an event called "applicationCreated". The newly created
     *   entity will also be provided to the handler.
     */
    .post(function(req, res, next)
    {
        var data = req.body;
        var ownerID = 1234;

        data.ownerID = ownerID;
        data.createdDate = Date.now();
        data.lastUpdatedDate = Date.now();

        applications.insert(data, {w:1}, function(err, result) 
        {
            if (result) 
            {
                onApplicationCreated.yield(result[0]);
                res.status(201).json(result[0]);
            }
            else
                res.status(500).json(err);
        });
    })
;

//----[ Routes for "/:codename" URI ]----------------------------------------------------

router.route('/:codename')

    /*
     * STORY 04:
     *   As an application developer, I want to use an application's business identifier,
     *   so I can view complete details about it.
     *
     *   Applications are composed by: name, description, icon URL, supported platforms,
     *   contact information (name and e-mail address), current status, codename, created
     *   date and last updated date.
     *
     *   The codename is an unique property among all applications. It can never be used
     *   by two different applications of the same user. Therefore, it can be considered as 
     *   the application's business identifier.
     */
    .get(function(req, res, next)
    {
        const user = req.user;
        const code = req.params.codename;
        const query = {'ownerID': user._id, 'codename': code};
        applications.findOne(query, function(err, results)
        {
            if (!err)
            {
                if (results)
                    res.status(200).json(results);
                else
                    res.status(404).end();    
            }
            else
                res.send(500).json(err);
        });
    })

    /*
     * STORY 05:
     *   As an application developer, I want to update an application, by providing it's
     *   codename and updated information, so all details are updated in persistence.
     * 
     *   Any information provided in the internal JSON, if eligible, will be updated upon
     *   successful validation applied.
     * 
     * STORY 06:
     *   As an API developer, I want to be notified whenever an application is updated, so
     *   I can act upon this event without the need to change original code, thus keeping
     *   my customization decoupled.
     *
     *   On success, it will emit an event called "applicationUpdated". The updated entity
     *   will also be provided to the handler. 
     */
    .put(function(req, res, next)
    {
        var codename = req.params.codename;
        var application = null;
        applicationUpdatedEvent.yield(application);
        res.status(200).json({'message':'Success, but not implemented.'});
    })

    /*
     * STORY 07:
     *   As an application developer, I want to delete an application, by providing it's
     *   codename, so the application is disabled, subscriptions are removed and unsent
     *   messages still in sending queue are cancelled.
     *
     * STORY 08:
     *   As an API developer, I want to be notified whenever an application is deleted, 
     *   so I can act upon this event without the need to change original code, thus
     *   keeping my customization decoupled.
     *
     *   On success, it will emit an event called "applicationDeleted". The informed ID
     *   (codename), target for deletion, will be provided to the handler.
     */
    .delete(function(req, res, next)
    {
        var codename = req.params.codename;
        applicationDeletedEvent.yield(codename);
        res.status(204).end();
    })
;

//----[ Other specific routes ]----------------------------------------------------------

/*
 * STORY 09:
 *   As an application developer, I want to use an application's business identifier,
 *   so I can view statistics about it.
 *
 *   Available statistics are: Last month's subscriptions, mostly used device platforms,
 *   device count (subscribed, active, inactive), notification count (messages sent to 
 *   specific devices, messages sent to a group of devices, broadcasts).
 */
router.get('/:codename/statistics', function(req, res)
{
    res.status(200).json({'message':'Success, but not implemented.'});
});

module.exports = router;