# Copyright (c) 2015 Canonical Ltd
#
#    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 json

from pylxd import base


class LXDContainer(base.LXDBase):
    # containers:

    def container_list(self):
        (state, data) = self.connection.get_object('GET', '/1.0/containers')
        return [container.split('/1.0/containers/')[-1]
                for container in data['metadata']]

    def container_running(self, container):
        (state, data) = self.connection.get_object(
            'GET',
            '/1.0/containers/%s/state' % container)
        data = data.get('metadata')
        container_running = False
        if data['status'] in ['RUNNING', 'STARTING', 'FREEZING', 'FROZEN',
                              'THAWED']:
            container_running = True
        return container_running

    def container_init(self, container):
        return self.connection.get_object('POST', '/1.0/containers',
                                          json.dumps(container))

    def container_update(self, container, config):
        return self.connection.get_object('PUT', '/1.0/containers/%s'
                                          % container, json.dumps(config))

    def container_defined(self, container):
        return self.connection.get_status('GET', '/1.0/containers/%s/state'
                                          % container)

    def container_state(self, container):
        (state, data) = self.connection.get_object(
            'GET', '/1.0/containers/%s/state' % container)
        return data['metadata']['status']

    def container_start(self, container, timeout):
        action = {'action': 'start', 'timeout': timeout}
        return self.connection.get_object('PUT', '/1.0/containers/%s/state'
                                          % container,
                                          json.dumps(action))

    def container_stop(self, container, timeout):
        action = {'action': 'stop', 'timeout': timeout}
        return self.connection.get_object('PUT', '/1.0/containers/%s/state'
                                          % container,
                                          json.dumps(action))

    def container_suspend(self, container, timeout):
        action = {'action': 'freeze', 'timeout': timeout}
        return self.connection.get_object('PUT', '/1.0/containers/%s/state'
                                          % container,
                                          json.dumps(action))

    def container_resume(self, container, timeout):
        action = {'action': 'unfreeze', 'timeout': timeout}
        return self.connection.get_object('PUT', '/1.0/containers/%s/state'
                                          % container,
                                          json.dumps(action))

    def container_reboot(self, container, timeout):
        action = {'action': 'restart', 'timeout': timeout}
        return self.connection.get_object('PUT', '/1.0/containers/%s/state'
                                          % container,
                                          json.dumps(action))

    def container_destroy(self, container):
        return self.connection.get_object('DELETE', '/1.0/containers/%s'
                                          % container)

    def get_container_log(self, container):
        (state, data) = self.connection.get_object(
            'GET', '/1.0/containers/%s?log=true' % container)
        return data['metadata']['log']

    def get_container_config(self, container):
        (state, data) = self.connection.get_object(
            'GET', '/1.0/containers/%s?log=false' % container)
        return data['metadata']

    def container_info(self, container):
        (state, data) = self.connection.get_object(
            'GET', '/1.0/containers/%s/state' % container)
        return data['metadata']

    def container_migrate(self, container):
        action = {'migration': True}
        (state, data) = self.connection.get_object(
            'POST', '/1.0/containers/%s' % container,
            json.dumps(action))
        return {
            'control': data['metadata']['control'],
            'criu': data['metadata']['criu'],
            'fs': data['metadata']['fs']
        }

    # file operations
    def get_container_file(self, container, filename):
        return self.connection.get_raw(
            'GET',
            '/1.0/containers/%s/files?path=%s' % (container, filename))

    def container_publish(self, container):
        return self.connection.get_object('POST', '/1.0/images',
                                          json.dumps(container))

    # misc operations
    def run_command(self, container, args, interactive, web_sockets, env):
        env = env or {}
        data = {'command': args,
                'interactive': interactive,
                'wait-for-websocket': web_sockets,
                'environment': env}
        return self.connection.get_object('POST', '/1.0/containers/%s/exec'
                                          % container, json.dumps(data))

    # snapshots
    def snapshot_list(self, container):
        (state, data) = self.connection.get_object(
            'GET',
            '/1.0/containers/%s/snapshots' % container)
        return [snapshot.split('/1.0/containers/%s/snapshots/%s/'
                               % (container, container))[-1]
                for snapshot in data['metadata']]

    def snapshot_create(self, container, config):
        return self.connection.get_object('POST',
                                          '/1.0/containers/%s/snapshots'
                                          % container,
                                          json.dumps(config))

    def snapshot_info(self, container, snapshot):
        return self.connection.get_object('GET',
                                          '/1.0/containers/%s/snapshots/%s'
                                          % (container, snapshot))

    def snapshot_rename(self, container, snapshot, config):
        return self.connection.get_object('POST',
                                          '/1.0/containers/%s/snapshots/%s'
                                          % (container, snapshot),
                                          json.dumps(config))

    def snapshot_delete(self, container, snapshot):
        return self.connection.get_object('DELETE',
                                          '/1.0/containers/%s/snapshots/%s'
                                          % (container, snapshot))

@@ -4583,16 +4583,95 @@
 eturn %7B%0A
+            'operation': str(data%5B'operation'%5D.split('/1.0/operations/')%5B-1%5D),%0A
         
@@ -4685,16 +4685,20 @@
 ntrol': 
+str(
 data%5B'me
@@ -4716,16 +4716,17 @@
 ontrol'%5D
+)
 ,%0A      
@@ -4739,16 +4739,20 @@
 'criu': 
+str(
 data%5B'me
@@ -4767,16 +4767,17 @@
 %5B'criu'%5D
+)
 ,%0A      
@@ -4788,16 +4788,20 @@
   'fs': 
+str(
 data%5B'me
@@ -4814,16 +4814,17 @@
 '%5D%5B'fs'%5D
+)
 %0A       

Update container migration