#!/usr/bin/env python2

import urllib2
import urllib

PORT = 8888
HOST = "127.0.0.1"
DEBUG = False

def call(cmd, path='', host=HOST, port=PORT):
    if DEBUG:
        url = "http://%s:%d/%s/%s" % (host, port, cmd, path)
        print url
    quoted_path = urllib.quote_plus(path)
    url = "http://%s:%d/%s/%s" % (host, port, cmd, quoted_path)
    if url[-1] == '/':
        url = url[:-1]
    try:
        ret = urllib2.urlopen(url)
        return ret
    except:
        print('nb failed: cmd={cmd}, path={path}'.format(cmd=cmd, path=path))

def open_url(path, host=HOST, port=PORT):
    call('n', path, host, port)

def new_url(path, host=HOST, port=PORT):
    call('new', path, host, port)

def add_dir(path, host=HOST, port=PORT):
    call('add_dir', path, host, port)


def open_notebook(fullpath):
    if os.path.isfile(fullpath):
        print 'found file'
        open_url(fullpath)
        return

    path, file = os.path.split(fullpath)
    if not file.endswith('ipynb'):
        file = file + '.ipynb'

    print 'opening new notebook'
    fullpath = os.path.join(path, file)
    new_url(fullpath)

def add_notebooks(action, filepath, cwd):
    fullpath = os.path.join(cwd, filepath)
    if action == "notebook":
        open_notebook(fullpath)
    elif action == "add-dir":
        add_dir(fullpath)

def _get_active_notebooks():
    import json
    jstring = call('active_notebooks').read()
    data = json.loads(jstring)
    return data

def list_kernels():
    data = _get_active_notebooks()
    out = []
    out.append("Active Kernels:")
    out.append("====================")

    for i, f in enumerate(data['files']):
        s = "[{0}] {1}: {2}".format(i, f['name'], f['kernel_id'])
        out.append(s)
    out.append("====================")
    print "\n".join(out)

def attach(kernel):
    try:
        pos = int(kernel)
        data = _get_active_notebooks()
        notebook = data['files'][pos]
    except:
        pass

    if notebook:
        start_with_notebook(notebook)

def start_with_notebook(notebook):
    """
        Start a terminal app attached to a notebook
    """
    from IPython.frontend.terminal.ipapp import TerminalIPythonApp
    kernel = 'kernel-{0}.json'.format(notebook['kernel_id'])
    # TODO support other submodules like qtconsole
    argv = ['console', '--existing', kernel]
    app = TerminalIPythonApp.instance()
    app.initialize(argv)
    app.start()


if __name__ == '__main__':
    import argparse
    import os
    parser = argparse.ArgumentParser(description="Start a notebook");

    parser.add_argument('action', nargs="?", action="store", default=None)
    parser.add_argument('target', nargs="?", action="store")

    args = parser.parse_args()

    target = args.target
    action = args.action
    cwd = os.getcwd()

    if not action and not target:
        action = 'list'

    if not target and action != 'list':
        target = action
        action = 'notebook'

    if action in ['add-dir', 'notebook']:
        add_notebooks(action, target, cwd)

    if action in ['list']:
        list_kernels()

    if action in ['attach']:
        attach(target)
