#!/usr/bin/env python
# -*- coding: utf-8 -*-

__copyright__ = """
   pySART - Simplified AUTOSAR-Toolkit for Python.

   (C) 2010-2021 by Christoph Schueler <cpu12.gems.googlemail.com>

   All Rights Reserved

   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; either version 2 of the License, or
   (at your option) any later version.

   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.

   s. FLOSS-EXCEPTION.txt
"""
__author__ = "Christoph Schueler"
__version__ = "0.1.0"

import itertools
import os
import pathlib

import chardet


def slicer(iterable, sliceLength, converter=None):
    if converter is None:
        converter = type(iterable)
    length = len(iterable)
    return [
        converter(*(iterable[item : item + sliceLength]))
        for item in range(0, length, sliceLength)
    ]


import sys

if sys.version_info.major == 3:
    from io import BytesIO as StringIO
else:
    try:
        from cStringIO import StringIO
    except ImportError:
        from StringIO import StringIO


def runningOnTravis():
    return os.environ.get("TRAVIS") == "true"


def createStringBuffer(*args):
    """Create a string with file-like behaviour (StringIO on Python 2.x)."""
    return StringIO(*args)


CYG_PREFIX = "/cygdrive/"


def cygpathToWin(path):
    if path.startswith(CYG_PREFIX):
        path = path[len(CYG_PREFIX) :]
        driveLetter = "{0}:\\".format(path[0])
        path = path[2:].replace("/", "\\")
        path = "{0}{1}".format(driveLetter, path)
    return path


import ctypes


class StructureWithEnums(ctypes.Structure):
    """Add missing enum feature to ctypes Structures."""

    _map = {}

    def __getattribute__(self, name):
        _map = ctypes.Structure.__getattribute__(self, "_map")
        value = ctypes.Structure.__getattribute__(self, name)
        if name in _map:
            EnumClass = _map[name]
            if isinstance(value, ctypes.Array):
                return [EnumClass(x) for x in value]
            else:
                return EnumClass(value)
        else:
            return value

    def __str__(self):
        result = []
        result.append("struct {0} {{".format(self.__class__.__name__))
        for field in self._fields_:
            attr, attrType = field
            if attr in self._map:
                attrType = self._map[attr]
            value = getattr(self, attr)
            result.append(
                "    {0} [{1}] = {2!r};".format(attr, attrType.__name__, value)
            )
        result.append("};")
        return "\n".join(result)

    __repr__ = __str__


def flatten(*args):
    result = []
    for arg in list(args):
        if isinstance(arg, (list, tuple)):
            result.extend(flatten(*arg))
        else:
            result.append(arg)
    return result


import subprocess


class CommandError(Exception):
    pass


def runCommand(cmd):
    proc = subprocess.Popen(
        cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
    )
    result = proc.communicate()
    proc.wait()
    if proc.returncode:
        raise CommandError("{0}".format(result[1]))
    return result[0]


from unicodedata import normalize


def nfc_equal(str1, str2):
    return normalize("NFC", str1) == normalize("NFC", str2)


def fold_equal(str1, str2):
    return normalize("NFC", str1).casefold() == normalize("NFC", str2).casefold()


def detect_encoding(file_name: str) -> str:
    """Detect encoding of a text file.

     Parameters
    ----------
    file_name: str

    Returns
    -------
    str: Useable as `encoding` paramter to `open`.
    """
    if isinstance(file_name, pathlib.WindowsPath):
        file_name = str(file_name)
    with open(file_name, "rb") as inf:
        data = inf.read()
    encoding = chardet.detect(data).get("encoding")
    return encoding
