var _    = require('underscore');
var nolp = require('./lib/nolp/nolp.js');
var ups  = require('./lib/ups/ups.js');

/**
 * available delivery services
 *
 * @var array of strings
 * @private
 */
var availableServices = [
    "dhl",
    "ups"
];

/**
 * retrieves the status of a package sent with packet delivery service.
 *
 * A callback will be called with an tracking object:
 *
 *   {
 *      // contains the status of the tracking request
 *      // is true on success, false otherwise
 *      // use the issues array for human-readable error messages on failure.
 *      "status": <boolean>
 *
 *      // contains tracking data to the packet
 *      "data": {
 *
 *           // flag to sign wether packet has arrived ord not.
 *           "arrived": <boolean>,
 *
 *           // a string containing the current delivery state (delivery service dependent)
 *           "status": <string>,
 *
 *           // an array of objects explaining the progress in detail
 *           // there can be zero to Math.Infinity entries here.
 *           "steps": [
 *                {
 *                    "date":     <string> // Unix Timestamp
 *                    "location": <string> // location of the step
 *                    "status":   <string> // message
 *                }
 *           ]
 *       },
 *
 *       // an array containing strings with problems and errors on failure.
 *       "issues": [
 *       ]
 *   }
 *
 * @param object packet {"service": <string>, "id": <string>}
 * @param function callback get called with a status object
 * @returns boolean true on succesful call, false otherwise
 * @access public
 * @final
 */
this.track = function track (packet, callback) {

    if (typeof packet == "undefined") {
        console.log("No packet definition given.");
        return false;
    }

    if (typeof packet.id == "undefined") {
        console.log("No packet id given.");
        return false;
    }

    if (typeof packet.service != "string") 


    if (!this.isAvailableService(packet.service)) {
        console.log("Delivery service " + packet.service + " is not available.");
        return false;
    }

    if (typeof callback != "function") {
        console.log("No callback function given.");
        return false;
    }

    var deliveryService = getDeliveryService(packet.service);

    deliveryService.get(packet.id, function (error, page) {

        if (error !== null) {

            callback({
                "status": false,
                "data": {
                    // no data sadly :(
                },
                "issues": [
                    "Could not retrieve status page."
                ]
            });

            return;
        }

        deliveryService.parse(page, function (error, track) {

            if (error !== null) {
                callback({
                    "status": false,
                    "data": {
                        // no data sadly :(
                    },
                    "issues": [
                        "Could not parse status page."
                    ]
                });

                return;
            }

            deliveryService.normalize(track, function (error, model) {

                if (error !== null) {
                    callback({
                        "status": false,
                        "data": {
                            // no data sadly :(
                        },
                        "issues": [
                            "Could not normalize parsed data."
                        ]
                    });

                    return;
                }

                callback({
                    "status": true,
                    "data":   model,
                    "issues": [
                        // no issues \o/
                    ]
                });
            });
        });
    });

    return true;
};

/**
 * checks if service is available.
 *
 * @param string service name of service
 * @return boolean
 * @access public
 * @final
 */
this.isAvailableService = function isAvailableService (service) {

    if (typeof service == "undefined") {
        return false;
    }

    if (_.indexOf(availableServices, service) === -1) {
        return false;
    }

    return true;
}

/**
 * gives the delivery service
 *
 * @param string serviceName name of delivery service
 * @return controller|null іf serviceName could not map
 * @access private
 * @final
 */
function getDeliveryService (serviceName) {

    switch (serviceName) {
    case "dhl":
        return nolp;
    case "ups":
        return ups;
    }

    return null;
}

{
        console.log("No packet service given.");
        return false;
    }