#!/usr/bin/env python

# This script manages running a bunch of space servers to generate a single space.

import server
import socket
import time

nservers = 2
layout = (2, 1, 1)
port_base = 6666

hostname = socket.gethostname()

blocksize = (200, 8000, 8000)
center = (0,0,0)

pinto_ip = hostname
pinto_port = 6665

n_cseg_servers = 0
n_cseg_upper_servers = 1
cseg_ip = hostname
cseg_port_base = 6235
cseg_service_tcp_port = 6234 # The port space servers connect on
oseg_prefix = 'myspace-'

http_command_port_base = 9000

# Currently we need to generate all of these settings before starting up since
# they go into a file that is only read once
def generate_ip_file():
    f = open('servermap.txt', 'w')
    # And the real data
    for ss in range(nservers):
        internal_port = port_base + 2*ss
        external_port = internal_port + 1
        print >>f, hostname + ':' + str(internal_port) + ':' + str(external_port)
    f.close()

def generate_cseg_ip_file():
    # This servermap is used for cseg servers to contact each other (separate
    # from the port used for space servers to connect to them)
    f = open('cseg_servermap.txt', 'w')
    # And the real data
    for cs in range(n_cseg_servers):
        internal_port = cseg_port_base + 2*cs
        external_port = internal_port + 1
        print >>f, hostname + ':' + str(internal_port) + ':' + str(external_port)
    f.close()

def get_region_and_layout():
    half_extents = [ block * num / 2 for block,num in zip(blocksize, layout)]
    neg = [ -x for x in half_extents ]
    pos = [ x for x in half_extents ]
    region = "<<%f,%f,%f>,<%f,%f,%f>>" % (neg[0]+center[0], neg[1]+center[1], neg[2]+center[2], pos[0]+center[0], pos[1]+center[1], pos[2]+center[2])
    layout_str = "<" + str(layout[0]) + "," + str(layout[1]) + "," + str(layout[2]) + ">"

    return (region, layout_str)



def startCSeg(**kwargs):
    if n_cseg_servers == 0: return;

    generate_cseg_ip_file()
    region, layout = get_region_and_layout()

    for cs in range(n_cseg_servers):
        args = [
            # CSeg server IDs can't overlap with space server
            # IDs. Also, they must be the smallest IDs
            '--cseg-id=%d' % (cs+1),

            '--servermap=tabular',
            '--cseg-servermap-options=--filename=cseg_servermap.txt',

            '--layout=%s' % (layout),
            '--region=%s' % (region),

            '--cseg-service-tcp-port=' + str(cseg_service_tcp_port),
            '--num-cseg-servers=' + str(n_cseg_servers),
            '--num-upper-tree-cseg-servers=' + str(n_cseg_upper_servers)
            ]
        server.RunCSeg(args, **kwargs)


def startPinto(**kwargs):
    args = [
        '--port=' + str(pinto_port),
        '--handler=rtreecut'
        ]
    server.RunPinto(args, **kwargs)


def startSpace(**kwargs):
    generate_ip_file()
    for ss in range(nservers):
        region, layout = get_region_and_layout()

        args = [
            '--id=%d' % (ss+1),

            '--servermap=tabular',
            '--servermap-options=--filename=servermap.txt',

            '--layout=%s' % (layout),
            '--region=%s' % (region),

            '--pinto=master',
            '--pinto-options=' + '--host=' + str(pinto_ip) + ' --port=' + str(pinto_port),

            '--oseg=redis',
            '--oseg-options=' + '--prefix=' + str(oseg_prefix),

            '--command.commander=http',
            '--command.commander-options=--port=' + str(http_command_port_base + ss)
            ]
        if n_cseg_servers > 0:
            args += [
                '--cseg=client',
                '--cseg-service-host=' + str(cseg_ip),
                '--cseg-service-tcp-port=' + str(cseg_service_tcp_port),
                ]

        server.RunSpace(ss, args, **kwargs)

def start(**kwargs):
    startCSeg(**kwargs)
    startPinto(**kwargs)
    time.sleep(5)
    startSpace(**kwargs)

# Options:
# with_xterm - run services in terminals
# debug - run services in gdb
# valgrind - run services in valgrind
# heapcheck - turn on heap checking to the specified level
# heapprofile - turn on heap profiling, storing data to the specified destination
# heapprofile_interval - when heap profiling is on, take a snapshot every time this many bytes (accumulated over all allocations) are allocated (100MB by default)
start(with_xterm=True, debug=True, valgrind=False, heapcheck=False, heapprofile=False, heapprofile_interval=100*1024*1024)

@@ -3772,16 +3772,318 @@
 wargs)%0A%0A
+def printOHTemplate(**kwargs):%0A    print%0A    print%0A    print %22To start an object host connecting to this space, use at least the following parameters:%22%0A    print%0A    print %22    cppoh %25s %25s%22 %25 (%0A        '--servermap=tabular',%0A        '--servermap-options=--filename=servermap.txt',%0A        )%0A    print%0A%0A
 def star
@@ -4188,16 +4188,47 @@
 wargs)%0A%0A
+    printOHTemplate(**kwargs)%0A%0A
 # Option

Print instructions for running OH against "cluster" in test_deploy.