# -*- Mode: Python -*-

# GDBus - GLib D-Bus Library
#
# Copyright (C) 2008-2011 Red Hat, Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General
# Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
#
# Author: David Zeuthen <davidz@redhat.com>

import distutils.version
import os
import sys


# pylint: disable=too-few-public-methods
class Color:
    """ANSI Terminal colors"""

    GREEN = "\033[1;32m"
    BLUE = "\033[1;34m"
    YELLOW = "\033[1;33m"
    RED = "\033[1;31m"
    END = "\033[0m"


def print_color(msg, color=Color.END, prefix="MESSAGE"):
    """Print a string with a color prefix"""
    if os.isatty(sys.stderr.fileno()):
        real_prefix = "{start}{prefix}{end}".format(
            start=color, prefix=prefix, end=Color.END
        )
    else:
        real_prefix = prefix
    sys.stderr.write("{prefix}: {msg}\n".format(prefix=real_prefix, msg=msg))


def print_error(msg):
    """Print an error, and terminate"""
    print_color(msg, color=Color.RED, prefix="ERROR")
    sys.exit(1)


def print_warning(msg, fatal=False):
    """Print a warning, and optionally terminate"""
    if fatal:
        color = Color.RED
        prefix = "ERROR"
    else:
        color = Color.YELLOW
        prefix = "WARNING"
    print_color(msg, color, prefix)
    if fatal:
        sys.exit(1)


def print_info(msg):
    """Print a message"""
    print_color(msg, color=Color.GREEN, prefix="INFO")


def strip_dots(s):
    ret = ""
    force_upper = False
    for c in s:
        if c == ".":
            force_upper = True
        else:
            if force_upper:
                ret += c.upper()
                force_upper = False
            else:
                ret += c
    return ret


def dots_to_hyphens(s):
    return s.replace(".", "-")


def camel_case_to_uscore(s):
    ret = ""
    insert_uscore = False
    prev_was_lower = False
    initial = True
    for c in s:
        # Keep initial underscores in camel case
        if initial and c == "_":
            ret += "_"
            continue
        initial = False

        if c.isupper():
            if prev_was_lower:
                insert_uscore = True
            prev_was_lower = False
        else:
            prev_was_lower = True
        if insert_uscore:
            ret += "_"
        ret += c.lower()
        insert_uscore = False
    return ret


def is_ugly_case(s):
    if s and s.find("_") > 0:
        return True
    return False


def lookup_annotation(annotations, key):
    if annotations:
        for a in annotations:
            if a.key == key:
                return a.value
    return None


def lookup_docs(annotations):
    s = lookup_annotation(annotations, "org.gtk.GDBus.DocString")
    if s is None:
        return ""
    else:
        return s


def lookup_since(annotations):
    s = lookup_annotation(annotations, "org.gtk.GDBus.Since")
    if s is None:
        return ""
    else:
        return s


def lookup_brief_docs(annotations):
    s = lookup_annotation(annotations, "org.gtk.GDBus.DocString.Short")
    if s is None:
        return ""
    else:
        return s


def version_cmp_key(key):
    # If the 'since' version is 'UNRELEASED', compare higher than anything else
    # If it is empty put a 0 in its place as this will
    # allow LooseVersion to work and will always compare lower.
    if key[0] == "UNRELEASED":
        v = "9999"
    elif key[0]:
        v = str(key[0])
    else:
        v = "0"
    return (distutils.version.LooseVersion(v), key[1])
