# -*- coding: utf-8 -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
import ulib.base.i_need_py23

__all__ = ('isquiet', 'isautoupdate', 'VcsDir')

import os
from os import path

from ulib.base.control import Status, OK_STATUS
from ulib.base.pager import page_file
from ulib.base.output import einfo
from ulib.base.tmpfiles import litemp, cltemp
from ulib.p.wop import find_uinstdir, get_uinst
from ulib.p.uinc import Updater, ConsoleOutput
from ulib.p.dirconf import DirConf

def isquiet(kw):
    return kw.get('quiet', False)
def isautoupdate(kw):
    return kw.get('auto_update', True)

def get_uincdirs():
    uincdirs = os.environ.get('UINCPATH', '').split(os.pathsep)
    uincdirs = filter(None, uincdirs)
    return uincdirs

class VcsDir:
    path = None
    rootdir = None

    def __init__(self, p, rootdir=None):
        self.path = path.abspath(p)
        if rootdir is not None: self.rootdir = rootdir

    def get_path(self):
        return self.path
    __str__ = get_path
    __repr__ = get_path

    def get_vcs_name(self):
        raise NotImplementedError

    def _is_vcsdir(self, p):
        raise NotImplementedError

    def _new_vcsdir(self, p):
        raise NotImplementedError

    def get_rootdir(self):
        if self.rootdir is None:
            p = self.path
            pp = path.split(p)[0]
            while self._is_vcsdir(pp):
                p = pp
                pp = path.split(p)[0]
            self.rootdir = self._new_vcsdir(p, True)
        return self.rootdir

    def get_reposurl(self):
        raise NotImplementedError

    def get_url(self):
        raise NotImplementedError

    def is_rootdir(self):
        return self.get_rootdir() is self

    def __under_rootp(self, p, rootp):
        cp = path.commonprefix((p, rootp))
        return cp == rootp or cp.startswith(rootp + '/')

    def get_updater(self, args):
        updater = Updater(args, context='uproject')
        updater.uincdirs = get_uincdirs()
        if updater.auto:
            rootp = self.get_rootdir().get_path()
            p = updater.args[0]
            if not self.__under_rootp(p, rootp):
                return None
        return updater

    def fold(self, pr=None, args=None, action=None):
        u = self.get_updater(args)
        if u is None: return False
        if not u.should_update()[0]: return False
        return u.update(Updater.FOLD)
        #XXX
        uinstdir = self.get_uinstdir()
        if uinstdir is None: return False
        if pr is None and args is None:
            uinst = get_uinst(uinstdir)
            pr, args = update_inc_params(['-q', '-C', uinst, '-f'], uinstdir)
        elif action is None:
            action = 'fold'
        update_inc(pr, args, action)
        return True

    def autofold(self, pr=None, args=None, action=None, **kw):
        if isautoupdate(kw): return self.fold(pr, args, action)
        else: return False

    def unfold(self, pr=None, args=None, action=None):
        u = self.get_updater(args)
        if u is None: return False
        if not u.should_update()[0]: return False
        return u.update(Updater.UNFOLD)
        #XXX
        uinstdir = self.get_uinstdir()
        if uinstdir is None: return False
        if pr is None and args is None:
            uinst = get_uinst(uinstdir)
            pr, args = update_inc_params(['-q', '-C', uinst], uinstdir)
        elif action is None:
            action = 'unfold'
        update_inc(pr, args, action)
        return True

    def autounfold(self, pr=None, args=None, action=None, **kw):
        if isautoupdate(kw): return self.unfold(pr, args, action)
        else: return False

    lang = None
    def set_LANG(self, lang='C'):
        self.lang = os.environ.get('LANG', None)
        os.environ['LANG'] = lang
    def restore_LANG(self):
        if self.lang is not None:
            os.environ['LANG'] = self.lang

    def add(self, *files, **kw):
        raise NotImplementedError

    def remove(self, *files, **kw):
        raise NotImplementedError

    def copy(self, fromf, tof, **kw):
        raise NotImplementedError

    def move(self, fromf, tof, **kw):
        raise NotImplementedError

    def mkdir(self, dir, **kw):
        raise NotImplementedError

    def commit(self, message, *files, **kw):
        raise NotImplementedError

    def status(self, **kw):
        raise NotImplementedError

    def update(self, **kw):
        raise NotImplementedError

    # par défaut, tag est effectué uniquement sur le rootdir. Si _tag_rootdir
    # est spécifié à False, alors l'opération est effectuée à partir du chemin
    # courant
    _tag_rootdir = True
    def is_tag_rootdir(self): return self._tag_rootdir
    def set_tag_rootdir(self, tag_rootdir): self._tag_rootdir = tag_rootdir

    def tag(self, name, message=None, **kw):
        raise NotImplementedError

    def diff_to(self, outfile=None, compare_with=None, **kw):
        raise NotImplementedError

    def diff(self, check_only=False, outputfile=None, compare_with_tag=None, **kw):
        li = litemp()
        try:
            outfile = outputfile or None
            status, outfile = self.diff_to(outfile=outfile)
            size = path.getsize(outfile)
            if check_only:
                return Status(size != 0)
            if outputfile is not None:
                return status
            else:
                if size == 0: einfo(u"Aucune différences détectées")
                else: page_file(outfile)
                return OK_STATUS
        finally:
            cltemp(li)
