#!/usr/bin/env python
"""
Copyright 2016 Open Networking Foundation (ONF)

Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>

    TestON is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 2 of the License, or
    (at your option) any later version.

    TestON is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with TestON.  If not, see <http://www.gnu.org/licenses/>.
"""

import json
import os
import re
import subprocess
from docker import Client
from docker import errors
from drivers.common.apidriver import API

class DockerApiDriver( API ):

    def __init__( self ):
        """
        Initialize client
        """
        self.name = None
        self.home = None
        self.handle = None
        super( DockerApiDriver, self ).__init__()

    def connect( self, **connectargs ):
        """
        Create Client handle to connnect to Docker server
        """
        try:
            for key in connectargs:
                vars( self )[ key ] = connectargs[ key ]
            self.name = self.options[ 'name' ]
            for key in self.options:
                if key == "home":
                    self.home = self.options[ 'home' ]
                    break
            if self.home is None or self.home == "":
                self.home = "/var/tmp"

            self.handle = super( DockerApiDriver, self ).connect()
            self.dockerClient = Client(base_url='unix://var/run/docker.sock')
            return self.handle
        except Exception as e:
            main.log.exception( e )

    def getListOfImages( self, repo="onosproject/onos" ):
        """
        Get the list of image tags
        """
        try:
            imageList = list( self.dockerClient.images( name=repo ) )
            imageListToSend = []
            duplicateTagDetected = 0
            for imageDict in imageList:
                if imageDict[ 'RepoTags' ] is not None:
                    if len( imageDict[ 'RepoTags' ] ) > 1:
                        duplicateTagDetected = 1
                    imageListToSend.append( imageDict['RepoTags'][0].encode('UTF8').split(':')[1] )
            return imageListToSend, duplicateTagDetected
        except Exception as e:
            main.log.exception( e )

    def dockerPull( self, onosRepo ="onosproject/onos", onosTag="latest" ):
        """
        Pulls Docker image from repository
        """
        try:
            main.log.info( self.name +
                           ": Pulling Docker image " + onosRepo + ":"+ onosTag )
            for line in self.dockerClient.pull( repository = onosRepo, \
                    tag = onosTag, stream = True ):
                    print "#",
            main.log.info(json.dumps(json.loads(line), indent =4))

            #response = json.dumps( json.load( pullResult ), indent=4 )
            if re.search( "for onosproject/onos:" + onosTag, line ):
                main.log.info( "onos docker image pulled is: " + line )
                return main.TRUE
            else:
                main.log.error( "Failed to download image from: " + onosRepo +":"+ onosTag )
                main.log.error( "Error respone: " )
                main.log.error( line )
                return main.FALSE
        except Exception:
            main.log.exception( self.name + ": Uncaught exception!" )
            main.cleanAndExit()

    def dockerCreateCT( self, onosImage="onosproject/onos:latest", onosNode="onos1" ):
        """
            Create a Docker container with a specific image
        """
        try:
            main.log.info( self.name +
                           ": Creating Docker container for node: " + onosNode )
            response = self.dockerClient.create_container( image=onosImage, \
                    tty=True, name=onosNode, detach=True )
            #print response
            #print response.get("Id")
            #print response.get("Warnings")
            if( str( response.get("Warnings") ) == 'None' ):
                main.log.info( "Created container for node: " + onosNode + "; container id is: " + response.get("Id") )
                return ( main.TRUE, response.get("Id") )
            else:
                main.log.info( "Noticed warnings during create" )
                return ( main.FALSE, null)
        except Exception:
            main.log.exception( self.name + ": Uncaught exception!" )
            main.cleanAndExit()

    def dockerStartCT( self, ctID ):
        """
            Start Docker container
        """
        try:
            main.log.info( self.name +
                           ": Starting Docker conatiner Id " + ctID )
            response = self.dockerClient.start( container = ctID )
            if response is None:
                main.log.info( "Started container for Id: " + ctID )
                return main.TRUE
            else:
                main.log.info( "Noticed warnings during start" )
                return main.FALSE
        except Exception:
            main.log.exception( self.name + ": Uncaught exception!" )
            main.cleanAndExit()

    def dockerStopCT( self, ctName ):
        """
            Stop docker container
        """
        try:
            main.log.info( self.name +
                           ": Stopping Docker conatiner for node " + ctName )
            response = self.dockerClient.stop( ctName )
            if response is None:
                main.log.info( "Stopped container for node: " + ctName )
                return main.TRUE
            else:
                main.log.info( "Noticed warnings during stop" )
                return main.FALSE
        except errors.NotFound:
            main.log.info( ctName + " not found! Continue on tests...")
            return main.TRUE
        except Exception:
            main.log.exception( self.name + ": Uncaught exception!" )
            #main.cleanAndExit()

    def dockerRestartCT( self, ctName ):
        """
            Restart Docker container
        """
        try:
            main.log.info( self.name +
                           ": Restarting Docker conatiner for node " + ctName )
            response = self.dockerClient.restart( ctName )
            if response is None:
                main.log.info( "Restarted container for node: " + ctName )
                return main.TRUE
            else:
                main.log.info( "Noticed warnings during Restart" )
                return main.FALSE
        except Exception:
            main.log.exception( self.name + ": Uncaught exception!" )
            main.cleanAndExit()

    def dockerCheckCTName( self, ctName):
        """
            Check Docker conatiner status
        """
        try:
            main.log.info( self.name +
                           ": Checking Docker Status for CT with 'Names'  " + ctName )
            namelist = [response["Names"] for response in self.dockerClient.containers(all=True) if not []]
            main.log.info("Name list is: " + str(namelist) )
            if( [ctName] in namelist):
                main.log.info( "Container " + ctName + " exists" )
                return main.TRUE
            else:
                main.log.info( "Container " + ctName + " does not exist" )
                return main.FALSE
        except errors.NotFound:
            main.log.warn( ctName + "not found! Continue with the tests...")
            return main.FALSE
        except Exception:
            main.log.exception( self.name + ": Uncaught exception! Continue tests..." )
            #main.cleanAndExit()

    def dockerRemoveCT( self, ctName ):
        """
            Remove Docker conatiner
        """
        try:
            main.log.info( self.name +
                           ": Removing Docker container for node " + ctName )
            response = self.dockerClient.remove_container( ctName, force=True )
            if response is None:
                main.log.info( "Removed container for node: " + ctName )
                return main.TRUE
            else:
                main.log.info( "Noticed warnings during Remove " + ctName)
                return main.FALSE
            main.log.exception(self.name + ": not found, continuing...")
        except errors.NotFound:
            main.log.warn( ctName + "not found! Continue with the tests...")
            return main.TRUE
        except Exception:
            main.log.exception( self.name + ": Uncaught exception! Continuing..." )
            #main.cleanAndExit()

    def dockerRemoveImage( self, imageRepoTag=None ):
        """
            Remove Docker image
        """
        rmResult = main.TRUE
        if self.dockerClient.images() is []:
            main.log.info( "No docker image found" )
            return rmResult
        else:
            imageList = [ image["Id"] for image in self.dockerClient.images()
                                        if image["RepoTags"] is None
                                           or imageRepoTag in image["RepoTags"] ]
            for id in imageList:
                try:
                    main.log.info( self.name + ": Removing Docker image " + id )
                    response = self.dockerClient.remove_image(id, force = True)
                    if response is None:
                        main.log.info( "Removed Docker image: " + id )
                        rmResult = rmResult and main.TRUE
                    else:
                        main.log.info( "Noticed warnings during Remove " + id )
                        rmResult = rmResult and main.FALSE
                except errors.NotFound:
                    main.log.warn( image + "not found! Continue with the tests...")
                    rmResult = rmResult and main.TRUE
                except Exception:
                    main.log.exception( self.name + ": Uncaught exception! Continuing..." )
                    rmResult = rmResult and main.FALSE
                    #main.cleanAndExit()
        return rmResult

    def fetchLatestClusterFile( self, branch="master" ):
        """
            Fetch onos-form-cluster file from a particular branch
        """
        try:
            command = "wget -N https://raw.githubusercontent.com/opennetworkinglab/\
                    onos/" + branch + "/tools/package/bin/onos-form-cluster"
            subprocess.call( command ) # output checks are missing for now
            command = "chmod u+x " + "onos-form-cluster"
            subprocess.call( command )
            return main.TRUE
        except Exception:
            main.log.exception( self.name + ": Uncaught exception!" )
            main.cleanAndExit()

    def onosFormCluster( self, onosIPs, cmdPath, user="karaf", passwd="karaf" ):
        """
            From ONOS cluster for IP addresses in onosIPs list
        """
        try:
            onosIPs = " ".join(onosIPs)
            command = "{}/onos-form-cluster -u {} -p {} {}".format( cmdPath,
                                                                    user,
                                                                    passwd,
                                                                    onosIPs )
            result = subprocess.call( command, shell=True )
            if result == 0:
                return main.TRUE
            else:
                main.log.info("Something is not right in forming cluster>")
                return main.FALSE
        except Exception:
            main.log.exception( self.name + ": Uncaught exception!" )
            main.cleanAndExit()

    def dockerIP( self, ctName ):
        """
            Fetch IP address assigned to specified node/container
        """
        try:
            output = self.dockerClient.inspect_container( ctName )
            nodeIP = output['NetworkSettings']['IPAddress']
            main.log.info( " Docker IP " + str(nodeIP) )
            return str(nodeIP)

        except Exception:
            main.log.exception( self.name + ": Uncaught exception!" )
            main.cleanAndExit()

