# -*- coding: utf-8 -*-
import json
import subprocess
import sys
import anytree as at
import necessaryFuncs as nf


def create_tree(root_json, root_node):
    con_name = root_json['name']

    if con_name is None:
        con_name = 'container'

    if con_name in ['__i3', 'topdock', 'bottomdock']:
        return None
    else:
        this_node = at.AnyNode(id=con_name,
                               parent=root_node,
                               con_id=root_json['id'],
                               workspace=False,
                               container=False)

    if con_name == 'container':
        this_node.container = True

    for a_node in root_json['nodes']:
        create_tree(a_node, this_node)


def fix_container_names(node):
    if node.id == 'container':
        node_name = ', '.join([x.id for x in node.children])
        node_name = 'container[' + node_name + ']'
        node.id = node_name


def rofi(options, program):
    '''Call dmenu with a list of options.'''
    cmd = subprocess.Popen(program,
                           shell=True,
                           stdin=subprocess.PIPE,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)
    stdout, _ = cmd.communicate('\n'.join(options).encode('utf-8'))
    return stdout.decode('utf-8').strip('\n')


# Get I3 tree
proc_out = subprocess.run(['i3-msg', '-t', 'get_tree'], stdout=subprocess.PIPE)
i3tree = json.loads(proc_out.stdout.decode('utf-8'))

# Create tree from the i3 tree output
root = at.AnyNode(id='r')
create_tree(i3tree, root)
root = root.children[0]

# Identify the workspaces
for display in root.children:
    for wk in display.children[0].children:
        wk.workspace = True

# Get the current workspace
proc_out = subprocess.run(['i3-msg', '-t', 'get_workspaces'], stdout=subprocess.PIPE)
wkList = json.loads(proc_out.stdout.decode('utf-8'))
focWkName = nf.getFocusedWK(wkList)

# Change the tree such that the workspaces are children to the root
# while ignoring the current workspace
root.children = [node
                 for node in at.PostOrderIter(root, filter_=lambda x: x.workspace)
                 if node.id != focWkName]

# If workspace contains only one container, then remove that container
for node in at.PostOrderIter(root, filter_=lambda x: x.workspace):
    if len(node.children) == 1:
        node.children = node.children[0].children

# If containers have only one element, then remove such containers
for node in at.PreOrderIter(root, filter_=lambda x: x.container):
    if len(node.children) == 1:
        node.children[0].parent = node.parent
        node.parent = None

# Create names for containers
for node in at.PreOrderIter(root, filter_=lambda x: x.container):
    fix_container_names(node)

# Create new names for nodes for diplay in Rofi
names_id_map = [[x+y.id, y.con_id] for x, _, y in at.RenderTree(root)]

# Call rofi
selected = rofi([x[0] for x in names_id_map[1:]], 'rofi -dmenu -i -format i')

if selected == '':
    sys.exit(0)

# Run the command
selected = int(selected)+1
command_to_run = ['i3-msg',
                  '[con_id=' + str(names_id_map[selected][1]) + '] ' +
                  'move --no-auto-back-and-forth container to workspace ' +
                  focWkName]
# print(command_to_run)
subprocess.call(command_to_run)