# -*- coding: utf-8 -*-

import hashlib
import os
import string
import random
import socket
import sys
import logging
import tempfile
import urllib.request
import urllib.parse
import configparser as cp

try:
    from i18nlib import _
except :
    from .i18nlib import _

####################
# Global variables #
####################

# Global directories
confdir = os.path.expanduser(os.path.join('~', '.dontpanic'))
currentdir = os.path.dirname(os.curdir)
tmpprefix='dontpanic'
tempdir = ''
for d in os.listdir(os.path.join('/',tempfile.template)):
    if d.startswith(tmpprefix):
        tempdir = os.path.join('/',tempfile.template,d)
        break
if tempdir == '':
    tempdir = tempfile.mkdtemp(prefix="dontpanic")

# Translation directories
localedir = os.path.join(currentdir, 'locale')
podir = os.path.join(currentdir, 'po')

# Util files
config_file = os.path.join(confdir, 'config.cfg')
lock_file = os.path.join(confdir, 'lock')
logfile = os.path.join(tempdir, "dontpanic.log")
watchlist_file = os.path.join(confdir, 'watchlist.pkl')

# Util global variables
progname = "dontpanic"
progurl = "http://3hg.toile-libre.org/dontpanic"
progversion = 2.0

defaultconf = {'startperc': 7,
               'uplimit': 20,
               'downlimit': -1,
               'searchengine': 'alphareign',
               'proxy_type': 'none',
               'proxy_hostname': '',
               'proxy_username': '',
               'proxy_password': ''
               }

WELCOMEMSG = [_("What do we watch tonight?"),
              _("Don't forget your towel"),
              _("Do you have pizza?"),
              _("Type and watch"),
              _("Turn off the lights"),
              _("Get some beer before searching")
              ]

logger = logging.getLogger(__name__)


def makedir(d):
    if not os.path.isdir(d):
        os.makedirs(d)


def prepdirs():
    makedir(confdir)
    makedir(tempdir)


def prepconfig():
    prepdirs()

def htmlget(url, params=None):
    opener = urllib.request.build_opener()
    opener.addheaders = [('User-agent', 'Mozilla/5.0')]
    if params != None: 
        p = urllib.parse.urlencode(params)
        if url.endswith('?'):
            url = '{}{}'.format(url,p)
            response = opener.open(url, timeout=10)
        else:
            p = p.encode('ascii')
            response = opener.open(url, p, timeout=10)
    else:
        response = opener.open(url)
    data = response.read()      
    text = data.decode('utf-8')
    response.close()
    return(text)

def islastversion():
    """
    check if running version is the last one
    """
    v = 0
    try:
        response = htmlget("{}/version".format(progurl))
        v = float(response)
    except Exception as e:
        logging.info("Can't check dontpanic version")
        logging.info(e)

    if progversion >= v:
        return True
    else:
        return False

def convb(nbbyte):
    """
    Convert a number of bytes to a good unit

    Args:
        nbbyte (int): Number to convert

    Return:
        Return a string
    """
    l = len(str(nbbyte))
    if l < 4:
        return "{0:.2f} B".format(nbbyte)
    elif l < 7:
        return "{0:.2f} kB".format(nbbyte / 1000)
    elif l < 10:
        return "{0:.2f} MB".format(nbbyte / 1000000)
    else:
        return "{0:.2f} GB".format(nbbyte / 1000000000)


def get_cache_size():
    size = 0

    for dirpath, dirnames, filenames in os.walk(tempdir):
        for f in filenames:
            fp = os.path.join(dirpath, f)
            size += os.path.getsize(fp)

    return convb(size)


def cleancache():
    import shutil

    for f in os.listdir(tempdir):
        path = os.path.join(tempdir, f)
        if os.path.isdir(path):
            shutil.rmtree(path)
        elif os.path.isfile(path):
            os.remove(path)


def simplifyname(name):
    """
    Remove weird characters from a research

    Args:
        name (str): String to format

    Return:
        Return a string without weird characters
    """
    valid_chars = "-_. {}{}".format(string.ascii_letters, string.digits)
    name = name.replace('_', ' ')
    name = name.replace('.', ' ')
    name = ''.join(c for c in name if c in valid_chars)

    return name


def save_config(confdic):
    """
    Save the configuration to a file

    Args:
        confdic (dict): is a dictionnary containing various options
    """
    config = cp.RawConfigParser()
    config.add_section('Configuration')
    for key in defaultconf.keys():
        config.set('Configuration', key, confdic[key])
    with open(config_file, 'w') as cf:
        config.write(cf)


def load_config():
    confdic = {}
    tosave = False
    try:
        config = cp.RawConfigParser()
        config.read(config_file)
        for key in defaultconf.keys():
            try:
                confdic[key] = config.get('Configuration', key)
            except Exception as e:
                logger.info(e)
                confdic[key] = defaultconf[key]
                tosave = True
    except IOError:
        # restore default config
        logger.info('fail at opening config. Restore defaults')
        save_config(defaultconf)
        return defaultconf

    if tosave:
        save_config(confdic)

    return confdic


def get_hash(name):
    readsize = 64 * 1024
    with open(name, 'rb') as f:
        data = f.read(readsize)
        f.seek(-readsize, os.SEEK_END)
        data += f.read(readsize)
    return hashlib.md5(data).hexdigest()


def randomtext(n):
    # stackoverflow.com/questions/2257441
    #   /random-string-generation-with-upper-case-letters-and-digits-in-python/23728630#23728630
    txt = ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(n))

    return txt


def is_running():
    """return  True if dontpanic is ready to browse"""
    running = False
    if os.path.isfile(lock_file):
        try:
            with open(lock_file, 'r') as l:
                port = l.read().strip()
        # Warning: Better handle the exception, but FileNotFoundError doesn't exist in Python 2.7
        # The handler exception in common to both the version of Python is IOError
        except IOError:  # If the file doesn't exist (for example: first run of Don't Panic)
            port = 0

        try:
            retval = htmlget("http://localhost:{}".format(port))

            # If we are here, Don't Panic is already running
            running = True
            logger.warning("{} is already running".format(progname))

        except Exception as e:
            # If we are here, Don't Panic is not running
            logger.warning(e)

    return running


def lock():
    """Allow just one instance"""
    if not is_running():
        # If we are here, Don't Panic is not running
        port = get_free_port()
        logger.warning("{} is not running, open a new instance on the port {}".format(progname, port))
        with open(lock_file, "w") as p:
            p.write(str(port))
        return port
    else:
        return False


def get_free_port():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(("", 0))
    port = s.getsockname()[1]
    s.close()

    return port


def which(program):
    #https://stackoverflow.com/questions/377017/test-if-executable-exists-in-python/377028#377028
    def is_exe(fpath):
        return os.path.isfile(fpath) and os.access(fpath, os.X_OK)

    fpath, fname = os.path.split(program)
    if fpath:
        if is_exe(program):
            return program
    else:
        for path in os.environ["PATH"].split(os.pathsep):
            path = path.strip('"')
            exe_file = os.path.join(path, program)
            if is_exe(exe_file):
                return exe_file

    return None



def setup_logging(verbose):
    if verbose == 1:
        level = logging.INFO
    elif verbose > 1:
        level = logging.DEBUG
    else:
        level = logging.WARNING

    # to uncomment! 
    logging.basicConfig(filename=logfile,
                        format='%(asctime)s %(module)s:%(funcName)s:%(message)s',
                        datefmt='%H:%M:%S',
                        level=level)
    logging.info("Logging level set to {}".format(logging.getLevelName(logging.root.getEffectiveLevel())))


# Dictionnary containing every string to translate in templates
tpl_msg = {'tpl_about': _("About"),
           'tpl_back_to_main': _('Back to main page'),
           'tpl_movie_or_serie': _('Movie or serie title'),
           'tpl_best_dvd': _("Best DVD's"),
           'tpl_popular_series': _('Popular series'),
           'tpl_configuration': _("Configuration"),
           'tpl_incache': _("in cache"),
           'tpl_remove_all_t': _("Remove all finished torrents"),
           'tpl_show_play_link': _("Show play link at"),
           'tpl_upload_limit': _("Set upload limit in kB (-1 is no limit):"),
           'tpl_download_limit': _("Set download limit in kB (-1 is no limit):"),
           'tpl_apply_changes': _("Apply General & Proxy changes"),
           'tpl_config_restart': _("Don't Panic must be restarted for some options to apply"),
           'tpl_footer_bg': _("Background image"),
           'tpl_footer_your': _("Your page"),
           'tpl_storage': _("Storage"),
           'tpl_general': _("General"),
           'tpl_admin': _("Administration"),
           'tpl_stopdp': _("Stop Don't Panic"),
           'tpl_yourpage': _("This is your page"),
           'tpl_unsubscribe': _("Unsubscribe"),
           'tpl_logout': _("Log out"),
           'tpl_watchlist': _("Watchlist"),
           'tpl_movies': _("Movies"),
           'tpl_series': _("Series"),
           'tpl_schres': _("Search Results"),
           'tpl_see_also': _("See also"),
           'tpl_director': _("Director: "),
           'tpl_writer': _("Writers: "),
           'tpl_actors': _("Actors: "),
           'tpl_extrawords': _("Subtitle (or any extra words):"),
           'tpl_searchon': _("Search on:"),
           'tpl_watchnow': _("Watch now"),
           'tpl_provided': _("Provided by"),
           'tpl_all': _("all"),
           'tpl_search': _("Search"),
           'tpl_clean': _("clean"),
           'tpl_google_translate': _("Translate with google"),
           'tpl_watch_nothing': _("At the moment you have seen nothing. "
                                  "Put yourself comfortable and try to watch something!"),
           'tpl_favourite_search_engine': _("Default search engine"),
           'tpl_proxy_type': _("Proxy type"),
           'tpl_proxy_hostname': _("Proxy hostname"),
           'tpl_proxy_username': _("Proxy username"),
           'tpl_proxy_password': _("Proxy password"),
           'tpl_proxy_type_exp': _("none : no proxy - socks4 : username is required - socks5 : username and password "
                                   "are ignored - socks5_pw : username and password are send to the proxy if "
                                   "necessary - http : http proxy, username and password are ignored - http_pw : "
                                   "http proxy with username/password authentication - i2p_proxy : i2p SAM proxy"),
           'tpl_proxy_explanations': _("These options let you configure a proxy to hide your ip. By default, all "
                                       "data is encrypted with dontpanic, so this solution is faster than a VPN. Note "
                                       "if you already have a VPN configured, the following is useless. See <a "
                                       "href='http://www.libtorrent.org/reference-Settings.html#proxy-settings'>here"
                                       "</a> for more information. You can find <a href='http://proxylist.hidemyass.com"
                                       "/'>a list of free proxy here</a> or <a href='http://www.samair.ru/proxy/'>here"
                                       "</a>."),
           'tpl_not_last_version': _("> Upgrade dontpanic")
           }

# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
