# -*- coding: utf-8 -*-
"""
Copyright (C) 2012 Fabio Erculiani

Authors:
  Fabio Erculiani

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 3.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
"""
import os
import subprocess
import shlex
try:
    import ConfigParser as configparser
except ImportError:
    import configparser

from gi.repository import GLib

from entropy.const import etpConst, const_convert_to_rawstring, \
    const_isunicode, const_is_python3
from entropy.core.settings.base import SystemSettings
from entropy.misc import ParallelTask

import entropy.tools

def build_application_store_url(app, sub_page):
    """
    take rigo.models.application.Application object
    and build up HTTP Entropy Application Store URL
    pointing to exact Application page.
    sub_page is used to load a specific part of the page,
    for example "ugc" can be passed to load URL/ugc page.
    """
    settings = SystemSettings()
    details = app.get_details()
    pkg_id, pkg_repo = details.pkg
    branch = settings['repositories']['branch']
    product = settings['repositories']['product']
    url = "%s/show/%s,%s,%s,%s,%s,%s/%s" % (
        etpConst['packages_website_url'],
        details.pkgname,
        pkg_id,
        pkg_repo,
        etpConst['currentarch'],
        branch,
        product,
        sub_page)
    return url

def build_register_url():
    """
    Build User Account Registration Form URL.
    """
    return os.path.join(etpConst['distro_website_url'], "register")

def open_url(url):
    """
    Open the given URL using xdg-open
    """
    def _open_url(url):
        subprocess.call(["xdg-open", url])
    task = ParallelTask(_open_url, url)
    task.name = "UrlOpen"
    task.daemon = True
    task.start()

def get_output(args):
    """
    Return the standard output and exit status generated by
    args.
    """
    read_end, write_end = None, None
    exit_st = 1
    output = ""
    try:
        read_end, write_end = os.pipe()
        with os.fdopen(write_end, "w") as stdout:
            exit_st = subprocess.call(
                args, stdout=stdout)
            # avoid blocking in case of no output
            stdout.write("\n")
        with os.fdopen(read_end, "r") as stdin:
            output = stdin.read()
    finally:
        if read_end is not None:
            try:
                os.close(read_end)
            except OSError:
                pass
        if write_end is not None:
            try:
                os.close(write_end)
            except OSError:
                pass
    return exit_st, output

def _query_filetype(path):
    """
    Query mime type of file path.
    """
    exit_st, output = get_output(
        ["xdg-mime", "query", "filetype", path])
    if exit_st != os.EX_OK:
        return None
    mime = output.split("\n")[0].strip()
    if not mime:
        return None
    return mime

def _get_default_desktop(mime):
    """
    Return default .desktop file for mimetype.
    """
    exit_st, output = get_output(
        ["xdg-mime", "query", "default", mime])
    if exit_st != os.EX_OK:
        return None
    desktop_name = output.split("\n")[0].strip()
    if not desktop_name:
        return None
    return desktop_name

def open_editor(path):
    """
    Open given path with the default editor and return
    a subprocess.Popen object.
    """
    mime = _query_filetype(path)
    if mime is None:
        return None

    plain_mime = "text/plain"
    desktop_name = _get_default_desktop(mime)
    if not desktop_name:
        if mime != plain_mime:
            desktop_name = _get_default_desktop(
                plain_mime)
    if not desktop_name:
        return None

    xdg_data_dirs = os.getenv(
        "XDG_DATA_DIRS",
        "/usr/share").split(":")
    desktop_path = None
    for xdg_data_dir in xdg_data_dirs:
        _desktop_path = os.path.join(
            xdg_data_dir, "applications",
            desktop_name)
        if os.path.exists(_desktop_path) and \
                os.path.isfile(_desktop_path):
            desktop_path = _desktop_path
            break
    if desktop_path is None:
        return None

    parser = configparser.RawConfigParser()
    read_files = parser.read([desktop_path])
    if desktop_path not in read_files:
        return None
    exec_string = parser.get("Desktop Entry", "Exec")
    # replace %F with %f
    # replace %u with %f
    # replace %U with %f
    # as per:
    # http://standards.freedesktop.org/desktop-entry-spec/latest
    # and also handle %% (which is the escape for single %)
    exec_string = exec_string.replace(" %F", " %f")
    exec_string = exec_string.replace(" %U", " %f")
    exec_string = exec_string.replace(" %u", " %f")
    if " %f" in exec_string:
        exec_string = exec_string.replace(
            " %f", " \"" + path + "\"")
    else:
        exec_string += " \""
        exec_string += path
        exec_string += "\""
    # shlex split() wants raw string
    exec_string = const_convert_to_rawstring(exec_string)
    args = shlex.split(exec_string)
    proc = subprocess.Popen(args)
    return proc

def escape_markup(text):
    """
    Escape markup text to use with GTK3 widgets.
    After escaping, text is converted to raw string
    from unicode (Python 2). brrr...
    """
    return \
        GLib.markup_escape_text(
            prepare_markup(text))

def prepare_markup(text):
    """
    Convert text to raw bytestring to make GTK3 happy.
    """
    if const_is_python3():
        return text  # str()-strings just work

    if const_isunicode(text):
        return \
            const_convert_to_rawstring(
                text, from_enctype=etpConst['conf_encoding'])
    return text
