"""
Contains the python specific FileManager.
"""
import ast
import re
from pyqode.core.api import TextBlockHelper
from pyqode.core.managers import FileManager


class PyFileManager(FileManager):
    """
    Extends file manager to override detect_encoding. With python, we can
    detect encoding by reading the two first lines of a file and extracting its
    encoding tag.

    """
    #: True to fold import statements on open.
    fold_imports = False

    #: True to fold docstring on open
    fold_docstrings = False

    def detect_encoding(self, path):
        """
        For the implementation of encoding definitions in Python, look at:
        - http://www.python.org/dev/peps/pep-0263/

        .. note:: code taken and adapted from
            ```jedi.common.source_to_unicode.detect_encoding```
        """
        with open(path, 'rb') as file:
            source = file.read()
            # take care of line encodings (not in jedi)
            source = source.replace(b'\r', b'')
            source_str = str(source).replace('\\n', '\n')

        byte_mark = ast.literal_eval(r"b'\xef\xbb\xbf'")
        if source.startswith(byte_mark):
            # UTF-8 byte-order mark
            return 'utf-8'

        first_two_lines = re.match(r'(?:[^\n]*\n){0,2}', source_str).group(0)
        possible_encoding = re.search(r"coding[=:]\s*([-\w.]+)",
                                      first_two_lines)
        if possible_encoding:
            return possible_encoding.group(1)
        return 'UTF-8'

    def open(self, path, encoding=None, use_cached_encoding=True):
        if encoding is None:
            encoding = self.detect_encoding(path)
        super(PyFileManager, self).open(
            path, encoding=encoding, use_cached_encoding=use_cached_encoding)
        try:
            folding_panel = self.editor.panels.get('FoldingPanel')
        except KeyError:
            pass
        else:
            # fold imports and/or docstrings
            blocks_to_fold = []
            sh = self.editor.syntax_highlighter

            if self.fold_imports and sh.import_statements:
                blocks_to_fold += sh.import_statements
            if self.fold_docstrings and sh.docstrings:
                blocks_to_fold += sh.docstrings

            for block in blocks_to_fold:
                if TextBlockHelper.is_fold_trigger(block):
                    folding_panel.toggle_fold_trigger(block)

    def clone_settings(self, original):
        super(PyFileManager, self).clone_settings(original)
        self.fold_docstrings = original.fold_docstrings
        self.fold_imports = original.fold_imports
