# -*- coding: utf-8 -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8

"""Des fonctions pour éditer des fichiers.
"""

__all__ = ('edit_file', 'edit_template')

import os, sys

from .base import isseq
from .env import get_editor, get_editor_options, get_editor_setrow
from .uio import EditorIO, _s
from .lines import Lines
from .args import split_args
from .tmpfiles import mktemp
from .paths import in_PATH
from .procs import spawn

# options, setrow, setcol, colplus
EDITOR_CAPS = {'emacs': ('', '+', ':', 1),
               'xemacs': ('', '+', ':', 1),
               'gvim': ('-f', '+', '', 0),
               'vim': ('-f', '+', '', 0),
               'vi': ('', '+', '', 0),
               }
def get_default_editors():
    """Retourner une liste d'éditeurs par défaut pour la plateforme en cours
    """
    if sys.platform.startswith('linux'):
        return ('emacs', 'xemacs', 'gvim', 'vim', 'vi')
    else:
        return ('xemacs', 'emacs', 'gvim', 'vim', 'vi')

def get_editor_caps():
    """Obtenir les caractéristiques de l'éditeur configuré.

    @return: (editor, options, setrow, setcol, colplus)
    """
    options = None
    setrow = None
    setcol = ''
    colplus = 0

    editor = get_editor()
    if editor is None:
        for editor in get_default_editors():
            if in_PATH(editor): break
        else:
            raise OSError("Unable to find a default editor. Please set UTOOLS_EDITOR.")

        if EDITOR_CAPS.has_key(editor):
            options, setrow, setcol, colplus = EDITOR_CAPS[editor]

    if options is None and setrow is None:
        options = split_args(get_editor_options())
        setrow = get_editor_setrow()
    if options is None and setrow is None and EDITOR_CAPS.has_key(editor):
        options, setrow, setcol, colplus = EDITOR_CAPS[editor]

    return editor, options, setrow or '', setcol or '', int(colplus)

def edit_file(file, row=None, col=None):
    """Lancer un éditeur pour éditer le fichier file.

    @return: le status d'exécution de l'éditeur.
    """
    editor, options, setrow, setcol, colplus = get_editor_caps()

    cmd = [editor]
    if options:
        if isseq(options): cmd.extend(options)
        else: cmd.append(options)
    if setrow and row is not None:
        row = int(row)
        opt = '%s%i' % (setrow, row)
        if setcol and col is not None:
            col = int(col)
            opt += '%s%i' % (setcol, col + colplus)
        cmd.append(opt)
    cmd.append(file)
    return spawn(*cmd)

def edit_template(template=None, strip_prefix=None, row=None, col=None, lines=None):
    """Obtenir une valeur éditée dans un éditeur.

    Un fichier temporaire vide est initialisé avec le contenu de template,
    puis le fichier est proposé à l'édition.

    A la sortie, toutes les lignes commençant par strip_prefix sont supprimée,
    et une instance de Lines avec les lignes du fichier est retourné.

    @return: lines
    @rtype: Lines
    """
    if lines is None:
        uio = EditorIO()
        lines = Lines(uio=uio)
    else:
        uio = lines.uio
        if uio is None:
            uio = EditorIO()
            lines.uio = uio

    ## préparer le fichier
    tmpf, tmpfile = mktemp('utools')
    try:
        if template is not None:
            template = uio.s(template)
            try: tmpf.write(template)
            finally: tmpf.close()
        else:
            tmpf.close()

        ## l'éditer
        edit_file(tmpfile, row, col)

        ## traiter le résultat
        lines.readlines(tmpfile)

        # enlever les préfixes
        if strip_prefix is not None:
            lines.filter(lambda l: not l.startswith(strip_prefix))

        # supprimer les lignes vides au début et à la fin
        while lines and not lines[0].strip(): del lines[0]
        while lines and not lines[-1].strip(): del lines[-1]

        return lines
    finally:
        os.remove(tmpfile)
