from .util import dbg, err
from os import path
import json
import copy
from .config import Config

JSON_PROFILE_NAME = "__internal_json_profile__"
JSON_LAYOUT_NAME = "__internal_json_layout__"


class ConfigJson(object):
    profile_to_use = 'default'
    
    def get_profile_to_use(self):
        return self.profile_to_use
        
    def build_single_tab_layout(self, layoutjson, vertical):
        dbg ('Budiling a single tab layout from json: %s ' % layoutjson)
        
        result = {
            'root': {
                'type': 'Window'
            }
        }
        
        self.build_container_layout(layoutjson, result, 'root', 0, vertical)
        
        return result
    
    def build_multi_tab_layout(self, layoutjson, vertical):
        dbg ('Budiling multi tabs layout from json: %s ' % layoutjson)
        
        tabs = {
            'type': 'Notebook',
            'parent': 'root',
            'labels': []
        }
        
        result = {
            'root': {
                'type': 'Window'
            },
            'tabs': tabs
        }
        
        counter = 0
        
        for tab in layoutjson:
            tabs['labels'].append(tab)
            self.build_container_layout(layoutjson[tab], result, 'tabs', counter, vertical)
            counter += 1
        
        return result
    
    def build_terminal_layout(self, layoutjson, children, parent, order):
        dbg ('Building a terminal from json: %s' % layoutjson)

        def from_json(layout_name, json_name=None):
            if json_name is None:
                json_name = layout_name

            if json_name in layoutjson:
                children[parent + "." + str(order)][layout_name] = layoutjson[json_name]

        children[parent + "." + str(order)] = {
            'type': 'Terminal',
            'order': order,
            'parent': parent,
            'profile': self.profile_to_use
        }

        from_json('command')
        from_json('title')

    def build_container_layout(self, layoutjson, children, parent, order, vertical):
        if len(layoutjson) == 1:
            layoutjson = layoutjson[0]
            
            if 'children' in layoutjson:
                self.build_container_layout(layoutjson['children'], children, parent, order, False if vertical else True)
            else:
                self.build_terminal_layout(layoutjson, children, parent, order)
            return
        
        dbg ('Building %s layout from json: %s' % ("vertical" if vertical else "horizontal", layoutjson))
        
        counter = 0
        actualparent = parent
        
        for pane in layoutjson:
            if counter < (len(layoutjson) - 1):
                containername = parent + "." + str(order) + "." + str(counter)
                ratio = (100 / (len(layoutjson) - counter)) / 100
                if 'ratio' in pane:
                    ratio = pane['ratio']
                children[containername] = {
                    'type': 'VPaned' if vertical else 'HPaned',
                    'order': order + counter,
                    'ratio': ratio,
                    'parent': actualparent
                }
                actualparent = containername
            
            if 'children' in pane:
                self.build_container_layout(pane['children'], children, containername, counter, False if vertical else True)
            else:
                self.build_terminal_layout(pane, children, containername, counter)
            
            counter += 1
    
    def get_layout(self, layoutjson):
        try:
            vertical = True
            if "vertical" in layoutjson:
                vertical = layoutjson["vertical"]
                del layoutjson["vertical"]

            if len(layoutjson) == 1:
                firstitem = next(iter(layoutjson.values()))
                result = self.build_single_tab_layout(firstitem, vertical)
            else:
                result = self.build_multi_tab_layout(layoutjson, vertical)
            
            dbg('Json layout is: %s' % result)
            return result
        except Exception as ex:
            err('Error building a layout from file %s' % ex)
            return None
    
    def get_profile(self, profilejson, baseprofile):
        try:
            result = copy.deepcopy(baseprofile)
            
            result.update(profilejson)
            
            dbg('Json profile is: %s' % result)
            return result
        except Exception as ex:
            err('Error building a profile from json file %s' % ex)
            return None
        
    def read_config(self, jsonfile):
        if not path.exists(jsonfile):
            dbg("Json config file is missing %s" % jsonfile)
            return None
        
        dbg('Loading config json from a file: %s' % jsonfile)
        
        layoutjson = None
        
        try:
            with open(jsonfile) as json_file:
                layoutjson = json.load(json_file)
        except Exception as ex:
            err('Error loading config json file %s (%s)' % (jsonfile, ex))
            return None
        
        return layoutjson

    def extend_config(self, jsonfile):
        configjson = self.read_config(jsonfile)
       
        if not configjson:
            return None
        
        config = Config()
        
        if 'profile' in configjson:
            profile = self.get_profile(configjson['profile'], config.base.profiles['default'])
            if profile:
                config.base.profiles[JSON_PROFILE_NAME] = profile
                self.profile_to_use = JSON_PROFILE_NAME
        
        if 'layout' in configjson:
            layout = self.get_layout(configjson['layout'])
            if layout:
                config.base.layouts[JSON_LAYOUT_NAME] = layout
                return JSON_LAYOUT_NAME
        
        return None
