#!/usr/bin/python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.

import os
import logging
import sys
import socket
from cloudutils.cloudException import CloudRuntimeException, CloudInternalException
from cloudutils.utilities import initLoging, bash
from cloudutils.configFileOps import  configFileOps
from cloudutils.globalEnv import globalEnv
from cloudutils.networkConfig import networkConfig
from cloudutils.syscfg import sysConfigFactory
from cloudutils.serviceConfig import configureLibvirtConfig

from optparse import OptionParser

def getUserInputs():
    print("Welcome to the CloudStack Agent Setup:")

    cfo = configFileOps("@AGENTSYSCONFDIR@/agent.properties")
    oldMgt = cfo.getEntry("host")

    mgtSvr = input("Please input the Management Server Hostname/IP-Address:[%s]"%oldMgt)
    if mgtSvr == "":
        mgtSvr = oldMgt
    try:
        socket.getaddrinfo(mgtSvr, 443)
    except:
        print("Failed to resolve %s. Please input a valid hostname or IP-Address."%mgtSvr)
        exit(1)

    oldToken = cfo.getEntry("zone")
    zoneToken = input("Please input the Zone Id:[%s]"%oldToken)

    if zoneToken == "":
        zoneToken = oldToken

    oldPod = cfo.getEntry("pod")
    podId = input("Please input the Pod Id:[%s]"%oldPod)

    if podId == "":
       podId  = oldToken

    oldCluster = cfo.getEntry("cluster")
    clusterId = input("Please input the Cluster Id:[%s]"%oldCluster)
    if clusterId == "":
        clusterId = oldCluster

    oldHypervisor = cfo.getEntry("hypervisor")
    if oldHypervisor == "":
        oldHypervisor = "kvm"

    hypervisor = input("Please input the Hypervisor type kvm/lxc:[%s]"%oldHypervisor)
    if hypervisor == "":
        hypervisor = oldHypervisor

    try:
        defaultNic = networkConfig.getDefaultNetwork()
    except:
        print("Failed to get default route. Please configure your network to have a default route")
        exit(1)

    defNic = defaultNic.name
    network = input("Please choose which network used to create VM:[%s]"%defNic)
    if network == "":
        if defNic == "":
            print("You need to specifiy one of Nic or bridge on your system")
            exit(1)
        elif network == "":
            network = defNic

    return [mgtSvr, zoneToken, network, podId, clusterId, hypervisor]

if __name__ == '__main__':
    initLoging("@AGENTLOGDIR@/setup.log")
    glbEnv = globalEnv()

    glbEnv.mode = "Agent"
    glbEnv.agentMode = "Agent"
    parser = OptionParser()
    parser.add_option("-a", action="store_true", dest="auto", help="auto mode")
    parser.add_option("-m", "--host", dest="mgt", help="Management server hostname or IP-Address")
    parser.add_option("-z", "--zone", dest="zone", help="zone id")
    parser.add_option("-p", "--pod", dest="pod", help="pod id")
    parser.add_option("-c", "--cluster", dest="cluster", help="cluster id")
    parser.add_option("-t", "--hypervisor", default="kvm", dest="hypervisor", help="hypervisor type")
    parser.add_option("-g", "--guid", dest="guid", help="guid")
    parser.add_option("-s", action="store_true", default=False, dest="secure", help="Secure and enable TLS for libvirtd")
    parser.add_option("--pubNic", dest="pubNic", help="Public traffic interface")
    parser.add_option("--prvNic", dest="prvNic", help="Private traffic interface")
    parser.add_option("--guestNic", dest="guestNic", help="Guest traffic interface")

    old_config = configFileOps("@AGENTSYSCONFDIR@/agent.properties")
    bridgeType = old_config.getEntry("network.bridge.type").lower()
    if bridgeType:
        glbEnv.bridgeType = bridgeType

    (options, args) = parser.parse_args()

    if not options.auto and options.secure:
        configureLibvirtConfig(True)
        print("Libvirtd with TLS configured")
        sys.exit(0)

    if options.auto is None:
        userInputs = getUserInputs()
        glbEnv.mgtSvr = userInputs[0]
        glbEnv.zone = userInputs[1]
        glbEnv.defaultNic = userInputs[2]
        glbEnv.pod = userInputs[3]
        glbEnv.cluster = userInputs[4]
        glbEnv.hypervisor = userInputs[5]
        #generate UUID
        glbEnv.uuid = old_config.getEntry("guid")
        if glbEnv.uuid == "":
            glbEnv.uuid = bash("uuidgen").getStdout()
    else:
        for para, value in list(options.__dict__.items()):
            if value is None:
                print("Missing operand:%s"%para)
                print("Try %s --help for more information"%sys.argv[0])
                sys.exit(1)

        glbEnv.uuid = options.guid
        glbEnv.mgtSvr = options.mgt
        glbEnv.zone = options.zone
        glbEnv.pod = options.pod
        glbEnv.cluster = options.cluster
        glbEnv.hypervisor = options.hypervisor
        glbEnv.nics.append(options.prvNic)
        glbEnv.nics.append(options.pubNic)
        glbEnv.nics.append(options.guestNic)

    glbEnv.secure = options.secure

    print("Starting to configure your system:")
    syscfg = sysConfigFactory.getSysConfigFactory(glbEnv)
    try:
        syscfg.config()
        print("CloudStack Agent setup is done!")
    except (CloudRuntimeException,CloudInternalException) as e:
        print(e)
        print("Try to restore your system:")
        try:
            syscfg.restore()
        except:
            pass
