/** @class */
jscape.ServerParameters = Class.extend(
    /** @lends {jscape.ServerParameters.prototype} */
{
    /** @const */
    ALL_HOSTS_ADDRESS: "0.0.0.0",

    /** @constructor */
    initialize: function(a, b, c, d, e, f, g, h, i, j, k, l) {
        this.appVersion = a;
        this.appInstanceId = b;
        this.interfaces = c || [];
        this.sslCiphers = d || [];
        this.sshKexes = e || [];
        this.sshCiphers = f || [];
        this.sshFipsCiphers = g || [];
        this.sshMacs = h || [];
        this.sshFipsMacs = i || [];
        this.sshCompressions = j || [];
        this.license = k || {};
        this.timeZone = l || "";
    },

    getInetAddresses: function() {
        var result = [this.ALL_HOSTS_ADDRESS];
        for (var i = 0; i < this.interfaces.length; i++) {
            var addresses = this.interfaces[i].addresses;
            for (var j = 0; j < addresses.length; j++) {
                result.push(addresses[j]);
            }
        }
        return result;
    },

    getSslCiphers: function() {
        return this.sslCiphers;
    }
});
jscape.ServerParameters.fromJSON = function(data) {
    return new jscape.ServerParameters(data.applicationVersion, data.applicationInstanceId, data.interfaces, data.sslCiphers,
                                       data.sshKexes, data.sshCiphers, data.sshFipsCiphers, data.sshMacs, data.sshFipsMacs, data.sshCompressions,
                                       data.license, data.timeZone);
};

/** @class */
jscape.ServerStatistics = Class.extend(
    /** @lends {jscape.ServerStatistics.prototype} */
{
    /** @constructor */
    initialize: function (a, b, c, d, e, f) {
        this.uptime = a;
        this.maxMemory = b;
        this.usedMemory = c;
        this.threads = d;
        this.managementConnections = e;
        this.domainStatistics = f || []
    }
});
jscape.ServerStatistics.fromJSON = function(data) {
    if (data) {
        data.domainStatistics = $.map(data.domainStatistics || [], jscape.DomainState.fromJSON);
        return $.extend(new jscape.ServerStatistics(), data);
    }
    return null;
};

/** @class */
jscape.DomainState = Class.extend(
    /** @lends {jscape.DomainState.prototype} */
{
    /** @constructor */
    initialize: function () {
        this.domainName = null;
        this.autoStartEnabled = false;
        this.fipsModeEnabled = false;
        this.startDate = null;
        this.stopDate = null;
        this.paused = false;
        this.totalSessions = 0;
        this.currentSessions = 0;
        this.currentTransfers = 0;
        this.filesUploaded = 0;
        this.filesDownloaded = 0;
        this.filesDeleted = 0;
        this.bytesUploaded = 0;
        this.bytesDownloaded = 0;
        this.uploadsQuota = null;
        this.currentUploadedBytes = null;
        this.downloadsQuota = null;
        this.currentDownloadedBytes = null;
        this.transfersQuota = null;
        this.currentTransferredBytes = null;
        this.connectionStatistics = [];
        this.log = null;
    },

    isRunning: function() {
        return this.startDate != null && this.stopDate == null;
    },

    toJSON: function() {
        return JSON.stringify(this);
    }
});
jscape.DomainState.fromJSON = function (data) {
    return $.extend(new jscape.DomainState() , data);
};

jscape.DomainStatus = {RUNNING: "RUNNING", PAUSED: "PAUSED", STOPPED: "STOPPED"};
jscape.DomainStatus.valueOf = function (statistics) {
    return statistics.isRunning() && statistics.paused
            ? jscape.DomainStatus.PAUSED
            : statistics.isRunning() ? jscape.DomainStatus.RUNNING : jscape.DomainStatus.STOPPED;
};

/** @class */
jscape.KeyPairAlgorithm = Class.extend(
    /** @lends {jscape.KeyPairAlgorithm.prototype} */
{
    /** @constructor */
    initialize: function(name, lengths) {
        this.name = name;
        this.lengths = [].concat(lengths);
    }
});
jscape.KeyPairAlgorithm.RSA = new jscape.KeyPairAlgorithm("RSA", [1024, 2048, 4096]);
jscape.KeyPairAlgorithm.DSA = new jscape.KeyPairAlgorithm("DSA", [1024]);
jscape.KeyPairAlgorithm.values = function() { return [jscape.KeyPairAlgorithm.RSA, jscape.KeyPairAlgorithm.DSA]; };
jscape.KeyPairAlgorithm.lengthsOf = function(algorithm) { return $.map($.grep(jscape.KeyPairAlgorithm.values(), function(item) { return item.name == algorithm; }), function(item) { return item.lengths; }); };

/** @class */
jscape.SignatureAlgorithm = Class.extend(
    /** @lends {jscape.SignatureAlgorithm.prototype} */
{
    /** @constructor */
    initialize: function(a, b) {
        this.hashAlgorithm = a;
        this.asymmetricalAlgorithm = b;
        this.name = (this.hashAlgorithm + "WITH" + this.asymmetricalAlgorithm).toUpperCase();
    },

    toJSON: function() {
        return this.hashAlgorithm;
    }
});
jscape.SignatureAlgorithm.SHA1_WITH_RSA = new jscape.SignatureAlgorithm("SHA1", "RSA");
jscape.SignatureAlgorithm.SHA1_WITH_DSA = new jscape.SignatureAlgorithm("SHA1", "DSA");
jscape.SignatureAlgorithm.SHA224_WITH_RSA = new jscape.SignatureAlgorithm("SHA224", "RSA");
jscape.SignatureAlgorithm.SHA224_WITH_DSA = new jscape.SignatureAlgorithm("SHA224", "DSA");
jscape.SignatureAlgorithm.SHA256_WITH_RSA = new jscape.SignatureAlgorithm("SHA256", "RSA");
jscape.SignatureAlgorithm.SHA256_WITH_DSA = new jscape.SignatureAlgorithm("SHA256", "DSA");
jscape.SignatureAlgorithm.SHA384_WITH_RSA = new jscape.SignatureAlgorithm("SHA384", "RSA");
jscape.SignatureAlgorithm.SHA384_WITH_DSA = new jscape.SignatureAlgorithm("SHA384", "DSA");
jscape.SignatureAlgorithm.SHA512_WITH_RSA = new jscape.SignatureAlgorithm("SHA512", "RSA");
jscape.SignatureAlgorithm.SHA512_WITH_DSA = new jscape.SignatureAlgorithm("SHA512", "DSA");
jscape.SignatureAlgorithm.MD5_WITH_RSA = new jscape.SignatureAlgorithm("MD5", "RSA");
jscape.SignatureAlgorithm.values = function() { return [jscape.SignatureAlgorithm.SHA1_WITH_RSA, jscape.SignatureAlgorithm.SHA1_WITH_DSA, jscape.SignatureAlgorithm.SHA224_WITH_RSA, jscape.SignatureAlgorithm.SHA224_WITH_DSA, jscape.SignatureAlgorithm.SHA256_WITH_RSA, jscape.SignatureAlgorithm.SHA256_WITH_DSA, jscape.SignatureAlgorithm.SHA384_WITH_RSA, jscape.SignatureAlgorithm.SHA384_WITH_DSA, jscape.SignatureAlgorithm.SHA512_WITH_RSA, jscape.SignatureAlgorithm.SHA512_WITH_DSA, jscape.SignatureAlgorithm.MD5_WITH_RSA]; };
jscape.SignatureAlgorithm.filter = function(func) { return $.grep(jscape.SignatureAlgorithm.values(), func || $.noop); };
jscape.SignatureAlgorithm.valueOf = function(value) { var entries = jscape.SignatureAlgorithm.filter(function(entry) { return entry.name === value || entry.hashAlgorithm === value; }); return entries.length ? entries[0] : null; };

/** @class */
jscape.ServerKeySummary = Class.extend(
    /** @lends {jscape.ServerKeySummary.prototype} */
{
    /** @constructor */
    initialize: function (a, b, c, d, e, f, g, h, i, j, k, l) {
        this.name = a || "";
        this.keyAlgorithm = b || "";
        this.keySize = parseInt(c) || 0;
        this.certificateSerialNumber = d || "";
        this.certificateBeginDate = parseInt(e) || 0;
        this.certificateEndDate = parseInt(f) || 0;
        this.certificateIssuer = g || "";
        this.certificateSubject = h || "";
        this.certificateSignatureAlgorithm = i || "";
        this.certificateSignature = j || "";
        this.revoked = k != undefined ? !!k : false;
        this.domains = l || [];
    }
});
jscape.ServerKeySummary.fromJSON = function(data) {
    return data ? new jscape.ServerKeySummary(data.name, data.keyAlgorithm, data.keySize, data.certificateSerialNumber, data.certificateBeginDate, data.certificateEndDate, data.certificateIssuer, data.certificateSubject, data.certificateSignatureAlgorithm, data.certificateSignature, data.revoked, data.domains) : null;
};

/** @class */
jscape.PublicKeySummary = Class.extend(
    /** @lends {jscape.PublicKeySummary.prototype} */
{
    /** @constructor */
    initialize: function (a, b, c) {
        this.name = a || "";
        this.keyAlgorithm = b || "";
        this.keySize = parseInt(c) || 0;
    }
});
jscape.PublicKeySummary.fromJSON = function(data) {
    return data ? new jscape.PublicKeySummary(data.name, data.keyAlgorithm, data.keySize) : null;
};

/** @class */
jscape.CertificateSummary = Class.extend(
    /** @lends {jscape.CertificateSummary.prototype} */
{
    /** @constructor */
    initialize: function (a, b, c, d, e, f, g, h, i, j, k) {
        this.name = a || "";
        this.keyAlgorithm = b || "";
        this.keySize = parseInt(c) || 0;
        this.certificateSerialNumber = d || "";
        this.certificateBeginDate = parseInt(e) || 0;
        this.certificateEndDate = parseInt(f) || 0;
        this.certificateIssuer = g || "";
        this.certificateSubject = h || "";
        this.certificateSignatureAlgorithm = i || "";
        this.certificateSignature = j || "";
        this.revoked = k != undefined ? !!k : false;
    }
});
jscape.CertificateSummary.fromJSON = function(data) {
    return data ? new jscape.CertificateSummary(data.name, data.keyAlgorithm, data.keySize, data.certificateSerialNumber, data.certificateBeginDate, data.certificateEndDate, data.certificateIssuer, data.certificateSubject, data.certificateSignatureAlgorithm, data.certificateSignature, data.revoked) : null;
};
jscape.CertificateSummary.isCertificateData = function(data) { return data && "certificateSerialNumber" in data; };

/** @class */
jscape.PgpKeySummary = Class.extend(
    /** @lends {jscape.PgpKeySummary.prototype} */
{
    /** @constructor */
    initialize: function(a, b, c, d, e, f, g, h) {
        this.name = a || "";
        this.keyAlgorithm = b || "";
        this.keySize = parseInt(c) || 0;
        this.encryptionAllowed = !!d || false;
        this.decryptionAllowed = !!e || false;
        this.signingAllowed = !!f || false;
        this.signatureVerificationAllowed = !!g || false;
        this.fingerprint = h || "";
    }
});
jscape.PgpKeySummary.fromJSON = function (data) {
    return data ? new jscape.PgpKeySummary(data.name, data.keyAlgorithm, data.keySize, data.encryptionAllowed, data.decryptionAllowed, data.signingAllowed, data.signatureVerificationAllowed, data.fingerprint) : null;
};

/** @class */
jscape.PgpSignatureDescriptor = Class.extend(
    /** @lends {jscape.PgpSignatureDescriptor.prototype} */
{
    /** @constructor */
    initialize: function(a, b, c, d) {
        this.signingKey = a || "";
        this.type = b || "";
        this.creationTime = parseInt(c) || 0;
        this.version = parseInt(d) | 0;
    }
});
jscape.PgpSignatureDescriptor.fromJSON = function(data) {
    return new jscape.PgpSignatureDescriptor(data.signingKey, data.type, data.creationTime, data.version);
};

jscape.KeyProvider = {
    fromJSON: function(data) {
        return data && (data.keyAlias || data.file)
               ? (data.keyAlias ? jscape.ServerKeyProvider.fromJSON(data) : jscape.FileKeyProvider.fromJSON(data))
               : null;
    }
};
/** @class */
jscape.FileKeyProvider = Class.extend(
    /** @lends {jscape.FileKeyProvider.prototype} */
{
    /** @constructor */
    initialize: function(a, b) {
        this.file = a || "";
        this.filePassword = b || "";
    }
});
jscape.FileKeyProvider.fromJSON = function(data) {
    return data ? new jscape.FileKeyProvider(data.file, data.filePassword) : null;
};

/** @class */
jscape.ServerKeyProvider = Class.extend(
    /** @lends {jscape.ServerKeyProvider.prototype} */
{
    /** @constructor */
    initialize: function(alias) {
        this.keyAlias = alias || "";
    }
});
jscape.ServerKeyProvider.fromJSON = function(data) {
    return data ? new jscape.ServerKeyProvider(data.keyAlias) : null;
};

/** @class */
jscape.NetworkInterfaceInfo = Class.extend(
    /** @lends {jscape.NetworkInterfaceInfo.prototype} */
{
    /** @constructor */
    initialize: function(a, b, c) {
        this.name = a;
        this.displayName = b || a;
        this.addresses = c || [];
    }
});

/** @class */
jscape.LogService = Class.extend(
    /** @lends {jscape.LogService.prototype} */
{
    /** @constructor */
    initialize: function (a) {
        this.type = a || jscape.LogService.Type.FILE;
    }
});
jscape.LogService.fromJSON = function(data) {
    return data ? $.extend(new jscape.LogService(), data) : null;
};
jscape.LogService.Type = {FILE: "FILE", DB: "DB"};
jscape.LogService.FILE_STRATEGY = {DAILY: "Daily", WEEKLY: "Weekly", MONTHLY: "Monthly", FILE_SIZE: "FileSize"};
jscape.LogService.file = function(directory, strategy, size) {
    return $.extend(new jscape.LogService(jscape.LogService.Type.FILE), {directory: directory, strategyName: strategy, fileSize: parseInt(size) || 0});
};
jscape.LogService.db = function(url, user, password, poolSize, ttl) {
    return $.extend(new jscape.LogService(jscape.LogService.Type.DB), {url: url, username: user, password: password, poolSize: poolSize, idleConnectionTTL: ttl});
};
jscape.LogService.typeOf = function(descriptor, defaultType) {
    return descriptor != null && $.inArray(descriptor.type, [jscape.LogService.Type.FILE, jscape.LogService.Type.DB]) != -1
            ? descriptor.type
            : defaultType || null;
};
/** @class */
jscape.SyslogService = Class.extend(
    /** @lends {jscape.SyslogService.prototype} */
{
    /** @constructor */
    initialize: function(host, port, facility, processName) {
        this.host = host || "";
        this.port = parseInt(port) || 0;
        this.facilityCode = parseInt(facility) || 1;
        this.processName = processName || "";
    }
});
jscape.SyslogService.fromJSON = function(data) {
    return data ? new jscape.SyslogService(data.host, data.port, data.facilityCode, data.processName) : null;
};

/** @class */
jscape.WebResources = Class.extend(
    /** @lends {jscape.WebResources.prototype} */
{
    /** @constructor */
    initialize: function(lang, displayName, properties) {
        this.lang = lang || "";
        this.displayName = displayName || lang;
        this.properties = properties || {};
    },

    isDefault: function() {
        return this.lang === "";
    },

    clone: function() {
        return new jscape.WebResources(this.lang, this.displayName, $.extend({}, this.properties));
    }
});
jscape.WebResources.fromJSON = function(data) {
    return new jscape.WebResources(data.lang, data.displayName, data.properties);
};

/** @class */
jscape.Page = Class.extend(
    /** @lends {jscape.Page.prototype} */
{
    /** @constructor */
    initialize: function(a, b, c) {
        this.records = $.isArray(a) ? a : [];
        this.recordIndex = parseInt(b) || 0;
        this.totalRecords = parseInt(c) || this.records.length;
    }
});
jscape.Page.fromJSON = function(data, recordsProvider) {
    return $.isPlainObject(data)
            ? new jscape.Page($.map(data.records || [], recordsProvider), data.recordIndex, data.totalRecords)
            : new jscape.Page($.map($.isArray(data) ? data : [], recordsProvider));
};
jscape.Page.requestParameters = function(params) {
    function parametrize(value) {
        return value ? value.replace(/([a-z])([A-Z])/g, "$1_$2").toUpperCase() : value;
    }
    var startIndex, count, query;
    if ($.isPlainObject(params)) {
        startIndex = params.page ? (params.page - 1) * params.rows : null;
        count = params.rows || null;
        query = $.extend({}, params);
        delete query.page;
        delete query.rows;
        query.sort = parametrize(query.sort);
        query.order = parametrize(query.order);
        query.field = parametrize(query.field);
    }
    return {startIndex: startIndex, count: count, query: query};
};
jscape.Page.datagridFormatter = function () {
    return function (page) {
        return $.isArray(page) ? {total: page.length, rows: page} : {total: page.totalRecords, rows: page.records};
    }
};