#!/usr/bin/env python
# -*- coding: utf-8 -*-

#    Copyright (C) 2014 Thibaut Lapierre <root@epheo.eu>. All Rights Reserved.
#
#    Licensed 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 docker
import json
from shaddock import model


class Image(object):
    def __init__(self, name, docker_host, docker_version):
        self.name = name
        self.containerconfig = model.ContainerConfig(self.name)
        self.docker_host = docker_host
        self.docker_version = docker_version
        self.dockerapi = docker.Client(base_url=self.docker_host,
                                       version=str(self.docker_version),
                                       timeout=10)

    def build(self, nocache):
        if self.containerconfig.tag is not None:
            for line in self.dockerapi.build(path=self.containerconfig.path,
                                             tag=self.containerconfig.tag,
                                             nocache=nocache):
                jsonstream = json.loads(line.decode())
                stream = jsonstream.get('stream')
                error = jsonstream.get('error')
                if error is not None:
                    print(error.rstrip())
                if stream is not None:
                    print(stream.rstrip())
        else:
            print("Unrecognized service name")

    def create(self):
        c_id = self.dockerapi.create_container(
            image=self.containerconfig.tag,
            name=self.name,
            detach=False,
            ports=self.containerconfig.ports,
            environment=model.get_vars_dict(),
            volumes=self.containerconfig.volumes,
            hostname=self.containerconfig.name)

        return c_id


class Container(object):
    def __init__(self, service_name, docker_host, docker_version):
        self.name = service_name
        self.containerconfig = model.ContainerConfig(self.name)
        self.tag = self.containerconfig.tag
        if self.containerconfig.privileged:
            self.privileged = self.containerconfig.privileged
        else:
            self.privileged = None
        if self.containerconfig.network_mode:
            self.network_mode = self.containerconfig.network_mode
        else:
            self.network_mode = 'bridge'
        self.docker_host = docker_host
        self.docker_version = docker_version
        self.dockerapi = docker.Client(base_url=self.docker_host,
                                       version=str(self.docker_version),
                                       timeout=10)
        info = self.get_info()
        self.id = info.get('id')
        self.ip = info.get('ip')
        self.hostname = info.get('hostname')
        self.started = info.get('started')
        self.created = info.get('created')

    def start(self):
        if self.started is False and self.created is True:
            print('Starting %s ...' % self.tag)
            self.dockerapi.start(
                    container=self.id,
                    binds=self.containerconfig.binds,
                    port_bindings=self.containerconfig.port_bindings,
                    privileged=self.privileged,
                    network_mode=self.network_mode)
        elif self.created is False:
            print('Creating image %s ...' % self.tag)
            image = Image(self.name, self.docker_host, self.docker_version)
            c_id = image.create()
            if c_id:
                print('Starting container ...')
                self.dockerapi.start(
                    container=c_id,
                    binds=self.containerconfig.binds,
                    port_bindings=self.containerconfig.port_bindings,
                    privileged=self.privileged,
                    network_mode=self.network_mode)

        return True

    def stop(self):
        if self.started is True:
            print('Stopping container %s ...' % self.tag)
            self.dockerapi.stop(self.id)

    def remove(self):
        self.stop()
        if self.created is True:
            print('Removing container %s ...' % self.id)
            self.dockerapi.remove_container(self.id)

    def restart(self):
        self.dockerapi.restart(self.id)

    def return_logs(self):
        if self.containerconfig.tag is not None:
            try:
                for line in self.dockerapi.logs(
                                       container=self.id,
                                       stderr=True,
                                       stdout=True,
                                       timestamps=False,
                                       stream=True):
                    print(line.decode('utf-8').rstrip())
            except (KeyboardInterrupt, SystemExit):
                return True

    def pull(self):
        for line in self.dockerapi.pull(self.tag, stream=True):
            print(json.dumps(json.loads(line), indent=4))

    def get_info(self):
        info = {}
        info['id'] = None
        info['ip'] = None
        info['hostname'] = None
        info['started'] = False
        info['created'] = False
        containers_list = self.dockerapi.containers(all=True)
        if containers_list:
            try:
                c_id = [item['Id'] for item in containers_list
                        if self.tag in item['Image']][0]
            except IndexError:
                c_id = None

            if c_id:
                container_info = self.dockerapi.inspect_container(c_id)
                config = container_info['Config']
                network = container_info['NetworkSettings']
                info['id'] = c_id
                info['ip'] = network['IPAddress']
                info['hostname'] = config['Hostname']
                info['created'] = True
                if info.get('ip'):
                    info['started'] = True
        return info

@@ -747,16 +747,27 @@
 t model%0A
+import sys%0A
 %0A%0Aclass 
@@ -4800,32 +4800,153 @@
 ag is not None:%0A
+%0A            # %22Fix%22 in order to not use the stream generator in Python2%0A            if (sys.version_info %3E (3, 0)):%0A    
             try:
@@ -4954,32 +4954,36 @@
                 
+   
+ 
 for line in self
@@ -5030,32 +5030,36 @@
                 
+    
 container=self.i
@@ -5100,16 +5100,20 @@
         
+   
+ 
 stderr=T
@@ -5113,24 +5113,28 @@
 tderr=True,%0A
+    
             
@@ -5208,24 +5208,28 @@
             
+   
+ 
 timestamps=F
@@ -5269,24 +5269,28 @@
             
+    
 stream=True)
@@ -5307,24 +5307,28 @@
             
+   
+ 
 print(line.d
@@ -5344,32 +5344,36 @@
 f-8').rstrip())%0A
+    
             exce
@@ -5416,32 +5416,36 @@
                 
+  
+  
 return True%0A%0A   
@@ -5431,32 +5431,371 @@
      return True
+%0A            else:%0A%0A                line = self.dockerapi.logs(container=self.id,%0A                                           stderr=True,%0A                                           stdout=True,%0A                                           timestamps=False,%0A                                           stream=False)%0A                print(line)
 %0A%0A    def pull(s

Fix compatibility Python2 and 3 for logs fct