"""Author: Rafal Slota
Copyright (C) 2015 ACK CYFRONET AGH
This software is released under the MIT license cited in 'LICENSE.txt'

Brings up a couchbase cluster.
"""

from __future__ import print_function

import re
import requests
import sys
import time

from . import common, docker, dns as dns_mod

COUCHBASE_READY_WAIT_SECONDS = 60


def _couchbase(cluster_name, num):
    return 'couchbase{0}_{1}'.format(num, cluster_name)


def config_entry(cluster_name, num, uid):
    return '{0}:11211'.format(common.format_hostname(_couchbase(cluster_name, num), uid))


def _node_up(command, cluster_name, num, dns, image, uid):
    hostname = common.format_hostname(_couchbase(cluster_name, num), uid)
    node = docker.run(
        image=image,
        name=hostname,
        hostname=hostname,
        detach=True,
        interactive=True,
        tty=True,
        dns_list=dns,
        command=command)

    return {
        'docker_ids': [node],
        'couchbase_nodes': [hostname]
    }


def _ready(container):
    ip = docker.inspect(container)['NetworkSettings']['IPAddress']
    url = 'http://{0}:8091/pools'.format(ip)
    try:
        r = requests.head(url, timeout=5)
        return r.status_code == requests.codes.ok
    except requests.ConnectionError:
        return False


def _wait_until(condition, containers):
    common.wait_until(condition, containers, COUCHBASE_READY_WAIT_SECONDS)


def _cluster_nodes(containers, cluster_name, master_hostname, uid):
    for num, container in enumerate(containers[1:]):
        hostname = common.format_hostname(_couchbase(cluster_name, num + 1), uid)
        docker.exec_(container,
                     command=["/opt/couchbase/bin/couchbase-cli", "rebalance", "-c", "{0}:8091".format(master_hostname),
                              "-u", "admin", "-p", "password", "--server-add={0}:8091".format(hostname),
                              "--server-add-username=admin" "--server-add-password=password"],
                 stdout=sys.stderr)


def up(image, dns, uid, cluster_name, nodes):

    dns_servers, dns_output = dns_mod.maybe_start(dns, uid)
    couchbase_output = {}

    command = '''/etc/init.d/couchbase-server start
bash'''

    for num in range(nodes):
        node_out = _node_up(command, cluster_name, num, dns_servers, image, uid)
        common.merge(couchbase_output, node_out)

    containers = couchbase_output['docker_ids']
    common.merge(couchbase_output, dns_output)

    _wait_until(_ready, containers)

    master_hostname = common.format_hostname(_couchbase(cluster_name, 0), uid)

    docker.exec_(containers[0],
                 command=["/opt/couchbase/bin/couchbase-cli", "cluster-init", "-c", "{0}:8091".format(master_hostname),
                          "--cluster-init-username=admin", "--cluster-init-password=password",
                          "--cluster-init-ramsize=512", "--services=data,index,query"],
                 stdout=sys.stderr)

    docker.exec_(containers[0],
                 command=["/opt/couchbase/bin/couchbase-cli", "bucket-create", "-c", "{0}:8091".format(master_hostname),
                          "-u", "admin", "-p", "password", "--bucket=default", "--bucket-ramsize=512"],
                 stdout=sys.stderr)

    if len(containers) > 1:
        _cluster_nodes(containers, cluster_name, master_hostname, uid)

    common.merge(couchbase_output, dns_output)

    return couchbase_output

@@ -1610,16 +1610,28 @@
 %0A       
+ assert 0 ==
  docker.
@@ -1718,17 +1718,18 @@
 %22, %22
-rebalance
+server-add
 %22, %22
@@ -1933,16 +1933,17 @@
 e=admin%22
+,
  %22--serv
@@ -1967,16 +1967,47 @@
 assword%22
+, %22--services=data,index,query%22
 %5D,%0A     
@@ -2606,24 +2606,70 @@
 ), uid)%0A%0A   
+ # Initialize database cluster%0A    assert 0 ==
  docker.exec
@@ -3028,16 +3028,56 @@
 rr)%0A%0A   
+ # Create default bucket%0A    assert 0 ==
  docker.
@@ -3319,16 +3319,26 @@
 ize=512%22
+, %22--wait%22
 %5D,%0A     
@@ -3365,24 +3365,60 @@
 ys.stderr)%0A%0A
+    # Create database cluster nodes%0A
     if len(c
@@ -3501,24 +3501,314 @@
 name, uid)%0A%0A
+    # Rebalance all added nodes%0A    assert 0 == docker.exec_(containers%5B0%5D,%0A                 command=%5B%22/opt/couchbase/bin/couchbase-cli%22, %22rebalance%22, %22-c%22, %22%7B0%7D:8091%22.format(master_hostname),%0A                          %22-u%22, %22admin%22, %22-p%22, %22password%22%5D,%0A                 stdout=sys.stderr)%0A%0A
     common.m

fix couchbase rebalance