/*
* Licensed Materials - Property of IBM Corp.
* IBM UrbanCode Build
* IBM UrbanCode Deploy
* IBM UrbanCode Release
* IBM AnthillPro
* (c) Copyright IBM Corporation 2002, 2014. All Rights Reserved.
*
* U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
* GSA ADP Schedule Contract with IBM Corp.
*/


package com.urbancode.air.plugin.f5

import iControl.Interfaces

public class F5Server {
    def props
    def serverUrlArray
    def serverHostAndPort
    def serverIp
    def long serverPort
    def username
    def password
    def interfaces
    def timeout
    def folder
    def version

    // Main constructor for the F5Server plugin. Gathers and parses general
    // input properties for establishing a connection to the F5 Server.
    // Sets the active partition
    public F5Server(Map<String,String> props) {
        this.props = props
        this.serverUrlArray = props['serverURL']?.split('://') as String[]
        this.serverHostAndPort = serverUrlArray[1]?.split(':') as String[]
        this.serverIp = serverHostAndPort[0]
        if (serverHostAndPort.length > 1) {
            //port specified
            this.serverPort = Long.parseLong(serverHostAndPort[1])
        }
        else if (serverUrlArray[0].toString().length() >= 5) {
            //https default
            println("No server port specifed.  Defaulting to 443")
            this.serverPort = Long.parseLong("443")
        }
        else {
            //http default
            println("No port specifed.  Defaulting to 80")
            this.serverPort = Long.parseLong("80")
        }

        this.username = props['username']
        this.password = props['password']

        if (props['timeout']) {
            this.timeout = Integer.parseInt(props['timeout'])
        } else {
            this.timeout = 10
        }

        setActiveFolder()
    }

    // Creates the connection between the F5 server and the plugin
    public Interfaces getConnection() {
        if (!interfaces){
            interfaces = new Interfaces()
            com.urbancode.air.XTrustProvider.install()
            println("Connecting to server $serverIp:$serverPort using timeout of $timeout second(s)")

            if (!interfaces.initialize(serverIp, serverPort, username, password))
                throw new Exception("Could not connect!")
        }
        return interfaces
    }

    // Retrieve the full version of the current F5 system. Trims it into an integer
    public int getMajorVersion() {
        if(!version) {
            def rawVersion = getConnection().getSystemSystemInfo().get_version()
            println "F5 version: $rawVersion"
            if (rawVersion && rawVersion.length() > 9) {
                rawVersion = rawVersion[0..(rawVersion.indexOf('.') - 1) ]
                version = Integer.parseInt(rawVersion.trim()[8..-1])
            }
            else {
                throw new Exception("Unknown version $rawVersion")
            }
        }

        return version
    }

    // Retrieves the partition name from the input properties and parses it into a useable format
    public String getFolderName() {
        if (!folder && props['partition']) {
            folder = props['partition'].trim().replaceAll('\\\\', '/')
            if (getMajorVersion() > 10) {
                if (!folder.startsWith('/')) {
                    folder = '/' + folder
                }
                while (folder[1] == '/') {
                    folder = folder[1..-1]
                }
                if (folder[-1] != '/') {
                    folder = folder + '/'
                }
            }
        }
        return folder
    }

    // Sets the active F5 partition to the location given by the input properties
    public void setActiveFolder() {
        if (getFolderName()) {
            if (getMajorVersion() > 10) {
                println "Setting current folder to ${getFolderName()}"
                getConnection().getSystemSession().set_active_folder(getFolderName())
            }
            else {
                println "Setting active partition to ${getFolderName()}"
                getConnection().getManagementPartition().set_active_partition(getFolderName())
            }
        }
    }
}