#!/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()
