from __future__ import unicode_literals
from django.conf import settings
from random import randint
from jinja2 import Environment, PackageLoader, select_autoescape
from api.utils.docker_api import (
    get_all_external_ports,
    get_internal_ip,
    execute_command,
    run_container,
    start_container,
    stop_container,
    copy_in,
    container_is_running
)
from api.utils.git_api import clone_repo
from api.utils.command import execute
from api.utils.email import send_email
from api.utils.logger import (
    info,
    error,
    warning
)
import os
import socket
import time
import unicodedata
import stringcase
import tarfile

'''
'''
def normalize_name(name = None):
    if not name:
        return name
    
    try:
        name = unicodedata.normalize('NFKD', name)
        name = name.encode('ASCII', 'ignore') 
    except TypeError:
        pass

    name = stringcase.trimcase(name)
    name = stringcase.lowercase(name)
    name = stringcase.snakecase(name)

    return name

'''
'''
def randomize_port():
    ports = settings.ODOO_PORTS_RANGE
    port = 0

    while not check_port_from_docker(port):
        time.sleep(1)
        port = randint(ports[0], ports[1])

    return port
    
'''
'''
def check_port(port=0):
    if port == 0:
        return False

    ok = False
    info('cheking port %d at %s' % (settings.EXTERNAL_IP, port))
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    try:
        s.bind((settings.EXTERNAL_IP, port))
        info('%s checked at %s is success' % (settings.EXTERNAL_IP, port))
        ok = True
    except socket.error:
        info('%s checked at %s is failed' % (settings.EXTERNAL_IP, port))
        ok = False

    
    s.close()
    return ok

'''
'''
def check_port_from_docker(port=0):
    if port == 0:
        return False

    if port in get_all_external_ports():
        return False
    
    return True

'''
'''
def check_name(name=None):
    if not name:
        return False

    full_path = os.path.join(settings.ODOO_ROOT_PATH, name)
    return os.path.exists(full_path)

'''
'''
def create_folders(name=None):
    if not name:
        return False

    folders = settings.ODOO_DEFAULT_FOLDERS
    for folder in folders:
        full_path = os.path.join(settings.ODOO_ROOT_PATH, name, folder.strip())
        os.makedirs(full_path)
        time.sleep(1)

    return True

'''
'''
def apply_permissions(name=None):
    if not name:
        return False
    
    full_path = os.path.join(settings.ODOO_ROOT_PATH, name)
    execute(['chmod', '-Rf', '777', full_path])

    return True

'''
'''
def create_configuration(name=None):
    if not name:
        return False

    conf_path = os.path.join(settings.ODOO_ROOT_PATH, name, 'config')

    if not os.path.exists(conf_path):
        return False

    env = Environment(
        loader=PackageLoader('api', 'templates'),
        autoescape=select_autoescape(['j2'])
    )

    template = env.get_template(settings.ODOO_CONF_FILENAME + '.j2')

    template_rendered = template.stream({
        'admin_password': settings.ODOO_ADMIN_PASSWORD, 
        'db_host': settings.ODOO_DB_HOST,
        'db_port': settings.ODOO_DB_PORT,
        'db_name': name, 
        'db_user': settings.ODOO_DB_USER, 
        'db_password': settings.ODOO_DB_PASSWORD
    })

    template_rendered.dump(os.path.join(conf_path, settings.ODOO_CONF_FILENAME + '.conf'))

    return True

'''
'''
def create_database(name=None):
    if not name:
        return False

    cmd = 'createdb -U %s %s' % (settings.ODOO_DB_USER, name)
    return execute_command(settings.ODOO_DB_CONTAINER, cmd)

'''
'''
def copy_database_seed():
    backup_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'files', 'odoo.tar')
    return copy_in(settings.ODOO_DB_CONTAINER, '/tmp', backup_path)

'''
'''
def restore_database(name=None):
    if not name:
        return False

    cmd = 'psql -U %s -d %s -f %s' % (settings.ODOO_DB_USER, name, '/tmp/odoo.sql')
    return execute_command(settings.ODOO_DB_CONTAINER, cmd)

'''
'''
def remove_database_seed():
    cmd = 'rm -f %s' % ('/tmp/odoo.sql')
    return execute_command(settings.ODOO_DB_CONTAINER, cmd)

'''
'''
def create_odoo_container(name=None, ports=[]):
    if not name:
        return False

    ports = dict(map(lambda p: ('%d/tcp' % 8069, p), ports))
    volumes = dict(map(lambda f: (os.path.join(settings.ODOO_ROOT_PATH, name, f.strip()), {
        'bind': settings.ODOO_DEFAULT_FOLDERS[f].strip(),
        'mode': 'rw'
    })  , settings.ODOO_DEFAULT_FOLDERS))

    run_container(
        settings.ODOO_IMAGE, 
        name, 
        ports, 
        volumes, 
        settings.INTERNAL_NETWORK_NAME,
        '150m',
        '150m'
    )
    
    time.sleep(5)

    return True

'''
'''
def get_odoo_internal_ip(name=None):
    if not name:
        return None

    return get_internal_ip(name)

'''
'''
def install_modules(system_name=None, module_names=[]):
    if not system_name:
        return {'error': 'system name is required'}

    if len(module_names) == 0:
        return {'error': 'module names is required'}

    # 1. check system path
    system_path = os.path.join(settings.ODOO_ROOT_PATH, system_name)

    if not os.path.exists(system_path):
        error('%s path not exists' % system_name)
        return {'error': 'system path not exists'}
    
    info('%s path checked' % system_name)

    # 2. check system status
    system_is_up = container_is_running(system_name)
    info('%s system state detected' % system_name)
    
    # 3. stop system container if necesary
    if system_is_up:
        stopped = stop_container(system_name)

        if not stopped:
            error('%s system cannot be stopped' % system_name)
            return {'error': 'cannot stop system'}
    
    info('%s system state successfully passed [state=%s]' % (system_name, system_is_up))

    for module_name in module_names:
        # 4. check module path and remove it
        module_path = os.path.join(system_path, 'custom-addons', module_name)

        if os.path.exists(module_path):
            execute(['rm', '-Rf', module_path])

        # 5. clone repo
        addons_path = os.path.join(system_path, 'custom-addons')
        cloned = clone_repo(module_name, addons_path)

        if not cloned:
            return {'error': 'cannot clone repo'}

        # 6. remove git data
        git_data_path = os.path.join(module_path, '.git')

        if os.path.exists(git_data_path):
            execute(['rm', '-Rf', git_data_path])
        
        try:
            execute(['chmod', '-R', '777', module_path])
        except Exception:
            pass
        
        info('%s is installed in %s system' % (module_name, system_name))

    # 7. start system container
    if system_is_up:
        started = start_container(system_name)

        if not started:
            error('%s system cannot be started' % system_name)
            return {'error': 'cannot start system'}

    info('all modules requested installed')
    return {'result': '%s installed' % module_name}

'''
'''
def install_module(system_name=None, module_name=None):
    return install_modules(system_name, [module_name])
