var Synergy = {
    params: {},
    session_id: null,
    api_version: null,

    setParams: function (params) {
        ['username', 'password', 'base_url'].forEach(function (field) {
            if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') {
                throw 'Required param is not set: ' + field + '.';
            }
        });

        Synergy.params = params;
        if (typeof Synergy.params.base_url === 'string' && !Synergy.params.base_url.endsWith('/')) {
            Synergy.params.base_url += '/';
        }
    },

    checkVersion: function () {
        if (Synergy.api_version !== null) {
            return;
        }

        var response, request = new HttpRequest();
        request.addHeader('Content-Type: application/json');

        response = request.post(Synergy.params.base_url + 'rest/version');

        if (request.getStatus() !== 200) {
            throw 'Get version request failed with status code ' + request.getStatus() + ': ' + response;
        }

        if (response !== null) {
            try {
                version_data = JSON.parse(response);
            }
            catch (error) {
                throw 'Failed to parse get version response received from device API.';
            }
        }
        else {
            throw 'No data received by get version request.';
        }

        if ('currentVersion' in version_data && 'minimumVersion' in version_data) {
            if (version_data['minimumVersion'] <= 1200 && version_data['currentVersion'] >= 1200) {
                Synergy.api_version = 1200;
            } else {
                throw 'API version is not supported.';
            }
        } else {
            throw 'Get version response does not contain version.';
        }
    },

    login: function () {
        if (Synergy.session_id !== null || Synergy.api_version === null) {
            return;
        }

        var response, request = new HttpRequest();
        request.addHeader('Content-Type: application/json');
        request.addHeader('X-API-Version: ' + Synergy.api_version);

        response = request.post(Synergy.params.base_url + 'rest/login-sessions', JSON.stringify({
            'userName': Synergy.params.username,
            'password': Synergy.params.password
        }));

        if (request.getStatus() !== 200) {
            throw 'Auth request failed with status code ' + request.getStatus() + ': ' + response;
        }

        if (response !== null) {
            try {
                auth_data = JSON.parse(response);
            }
            catch (error) {
                throw 'Failed to parse auth response received from device API.';
            }
        }
        else {
            throw 'No data received by auth request.';
        }

        if ('sessionID' in auth_data) {
            Synergy.session_id = auth_data['sessionID'];
        } else {
            throw 'Auth response does not contain session ID.';
        }
    },

    logout: function () {
        if (Synergy.session_id !== null && Synergy.api_version !== null) {
            var response, request = new HttpRequest();
            request.addHeader('Content-Type: application/json');
            request.addHeader('X-API-Version: ' + Synergy.api_version);
            response = request.delete(Synergy.params.base_url + 'rest/login-sessions');
        }
    },

    requestData: function (method) {
        if (Synergy.session_id === null || Synergy.api_version === null) {
            return;
        }

        request = new HttpRequest();
        request.addHeader('Auth: ' + Synergy.session_id);
        request.addHeader('X-API-Version: ' + Synergy.api_version);

        raw_data = request.get(Synergy.params.base_url + 'rest/' + method);

        if (request.getStatus() < 200 || request.getStatus() >= 300) {
            throw 'Request failed with status code ' + request.getStatus() + ': ' + raw_data;
        }

        if (raw_data !== null) {
            try {
                return JSON.parse(raw_data);
            }
            catch (error) {
                throw 'Failed to parse response received from device API.';
            }
        }
        else {
            throw 'No data received by ' + method + ' request.';
        }
    }
};

var methods = ['datacenters', 'enclosures', 'ethernet-networks', 'fabrics', 'fc-networks', 'hypervisor-managers', 'interconnects', 'logical-enclosures', 'racks', 'server-hardware', 'storage-pools', 'storage-systems', 'storage-volumes', 'uplink-sets'],
    data = {};

data['errors'] = {};

try {
    Synergy.setParams(JSON.parse(value));

    try {
        Synergy.checkVersion();
    }
    catch (error) {
        data.errors.version = error.toString();
    }

    try {
        Synergy.login();
    }
    catch (error) {
        data.errors.auth = error.toString();
    }

    if (!('auth' in data.errors) && !('version' in data.errors)) {
        for (var i in methods) {
            try {
                if (methods[i] === 'enclosures') {
                    var bays = ['applianceBays', 'crossBars', 'deviceBays', 'fanBays', 'partitions', 'powerSupplyBays', 'managerBays'];

                    enclosures = Synergy.requestData(methods[i]);

                    enclosures.members.forEach(function (enclosure) {
                        enclosure_name = enclosure.name;

                        for (var j in bays) {
                            bay = enclosure[bays[j]];

                            bay.forEach(function (b) {
                                b.enclosureName = enclosure_name;
                                enclosures.members[bays[j[b]]] = b;
                            });
                        }
                    });

                    data[methods[i]] = enclosures;
                }
                else {
                    data[methods[i]] = Synergy.requestData(methods[i]);
                }
            }
            catch (error) {
                data.errors[methods[i]] = error.toString();
            }
        }
    }
}
catch (error) {
    data.errors.params = error.toString();
}

try {
    Synergy.logout();
}
catch (error) {
}

if (Object.keys(data.errors).length !== 0) {
    errors = 'Failed to receive data:';
    for (var error in data.errors) {
        errors += '\\n' + error + ' : ' + data.errors[error];
    }
    data.errors = errors;
}
else {
    data.errors = '';
}

return JSON.stringify(data);