#!/usr/bin/python3

import pycol
from clicmd import *
import sys
import traceback
import textwrap

def callback(cmdline, kvargs):
    print("match: %s"%(str(kvargs)))

normal = "\033[0m"
bold = "\033[1m"

ip_list = []

def help_callback(cmdline, kvargs):
    wrapper = textwrap.TextWrapper(initial_indent="  ",
                                   subsequent_indent="  ")
    wrapper2 = textwrap.TextWrapper(initial_indent="  ",
                                   subsequent_indent="      ")
    for c in cmdline.context:
        # XXX if terminal supports it, use bold and italic
        print("%s%s%s"%(bold, c.to_expr(), normal))
        lines = c.get_help().split("\n")
        print("\n".join(wrapper.wrap(lines[0])))
        for l in lines[1:]:
            print("\n".join(wrapper2.wrap(l)))
        # XXX use a pager

def ip_callback_add(cmdline, kvargs):
    global ip_list
    if kvargs["<ip>"] in ip_list:
        print("already in list")
        return
    ip_list.append(kvargs["<ip>"])

def ip_callback_del(cmdline, kvargs):
    global ip_list
    ip_list.remove(kvargs["<saved-ip>"])

def ip_callback_info(cmdline, kvargs):
    global ip_list
    if "<saved-ip>" in kvargs:
        print("%s is in list"%kvargs["<saved-ip>"])
    else:
        print("%s is not in list"%kvargs["<ip>"])

ctx = PycolContext([
    CmdBuilder(
        expr = "toto a|b [coin] [bar]",
        token_desc = {
            "toto": TextCliCmd("toto", help_str = "help for toto"),
            "a": TextCliCmd("a", help_str = "help for a"),
            "b": TextCliCmd("b", help_str = "help for b"),
            "coin": TextCliCmd("coin", help_str = "help for coin"),
            "bar": TextCliCmd("bar", help_str = "help for bar"),
        },
        cb = callback,
        help_str = "help for command toto. This is a very very " +
        "long long help to check that the wrapper is able to " +
        "wrap the text properly."
    ),

    CmdBuilder(
        expr = "titi [pouet] <anytext> <count>",
        token_desc = {
            "titi": TextCliCmd("titi", help_str = "help for titi"),
            "pouet": TextCliCmd("pouet", help_str = "help for pouet"),
            "<anytext>": AnyTextCliCmd(help_str = "help for anytext"),
            "<count>": IntCliCmd(help_str = "help for count"),
        },
        cb = callback,
        help_str = "help for command titi"
    ),

    CmdBuilder(
        expr = "regexp <re>",
        token_desc = {
            "regexp": TextCliCmd("regexp", help_str = "help for regexp"),
            "<re>": RegexpCliCmd("0x([0-9a-fA-F])", help_str = "an hex number"),
        },
        cb = callback,
        help_str = "help for command regexp"
    ),

    CmdBuilder(
        expr = "ip add <ip>",
        token_desc = {
            "ip": TextCliCmd("ip", help_str = "help for ip"),
            "add": TextCliCmd("add", help_str = "help for add"),
            "<ip>": IPv4CliCmd(help_str = "An IPv4 address. The format of " +
                           "an IPv4 address is A.B.C.D, each letter is a number" +
                           "between 0 and 255."),
        },
        cb = ip_callback_add,
        help_str = "help for command ip"
    ),

    CmdBuilder(
        expr = "ip del <saved-ip>",
        token_desc = {
            "ip": TextCliCmd("ip", help_str = "help for ip"),
            "del": TextCliCmd("del", help_str = "help for del"),
            "<saved-ip>": ChoiceCliCmd(ip_list, help_str = "an IP previously " +
                                       "added"),
        },
        cb = ip_callback_del,
        help_str = "help for command ip"
    ),

    CmdBuilder(
        expr = "ip info <saved-ip>|<ip>", # XXX talk about prio !
        token_desc = {
            "ip": TextCliCmd("ip", help_str = "help for ip"),
            "info": TextCliCmd("info", help_str = "help for info"),
            "<saved-ip>": ChoiceCliCmd(ip_list, help_str = "an IP previously " +
                                       "added"),
            "<ip>": IPv4CliCmd(help_str = "An IPv4 address"),
        },
        cb = ip_callback_info,
        help_str = "help for command ip"
    ),

    CmdBuilder(
        expr = "file <file>",
        token_desc = {
            "file": TextCliCmd("file", help_str = "Help for file. The file " +
                           "can be either a directory or a regular file."),
            "<file>": FileCliCmd(help_str = "a file"),
        },
        cb = callback,
        help_str = "help for command file"
    ),

    CmdBuilder(
        expr = "help",
        token_desc = {
            "help": TextCliCmd("help", help_str = "help for help"),
        },
        cb = help_callback,
        help_str = "help for command toto"
    ),
])

cmdline = pycol.Cmdline()
cmdline.add_context("my_context", ctx)
cmdline.set_context("my_context")
cmdline.set_prompt("my_context> ")
cmdline.input_loop()
