#!/usr/bin/python -bO
# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

#
# dispatch-conf -- Integrate modified configs, post-emerge
#
#  Jeremy Wohl (http://igmus.org)
#
# TODO
#  dialog menus
#

from __future__ import print_function

from stat import ST_GID, ST_MODE, ST_UID
from random import random
import atexit, re, shutil, stat, sys
from os import path as osp
if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
	sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
import portage
portage._internal_caller = True
from portage import os
from portage import _unicode_decode
from portage.dispatch_conf import diffstatusoutput
from portage.process import find_binary, spawn

FIND_EXTANT_CONFIGS  = "find '%s' %s -name '._cfg????_%s' ! -name '.*~' ! -iname '.*.bak' -print"
DIFF_CONTENTS        = "diff -Nu '%s' '%s'"

# We need a secure scratch dir and python does silly verbose errors on the use of tempnam
oldmask = os.umask(0o077)
SCRATCH_DIR = None
while SCRATCH_DIR is None:
    try:
        mydir = "/tmp/dispatch-conf."
        for x in range(0,8):
            if int(random() * 3) == 0:
                mydir += chr(int(65+random()*26.0))
            elif int(random() * 2) == 0:
                mydir += chr(int(97+random()*26.0))
            else:
                mydir += chr(int(48+random()*10.0))
        if os.path.exists(mydir):
            continue
        os.mkdir(mydir)
        SCRATCH_DIR = mydir
    except OSError as e:
        if e.errno != 17:
            raise
os.umask(oldmask)

# Ensure the scratch dir is deleted
def cleanup(mydir=SCRATCH_DIR):
    shutil.rmtree(mydir)
atexit.register(cleanup)

MANDATORY_OPTS = [ 'archive-dir', 'diff', 'replace-cvs', 'replace-wscomments', 'merge' ]

def cmd_var_is_valid(cmd):
    """
    Return true if the first whitespace-separated token contained
    in cmd is an executable file, false otherwise.
    """
    cmd = portage.util.shlex_split(cmd)
    if not cmd:
        return False

    if os.path.isabs(cmd[0]):
        return os.access(cmd[0], os.EX_OK)

    return find_binary(cmd[0]) is not None

class dispatch:
    options = {}

    def grind (self, config_paths):
        confs = []
        count = 0

        config_root = portage.settings["EPREFIX"] or os.sep
        self.options = portage.dispatch_conf.read_config(MANDATORY_OPTS)

        if "log-file" in self.options:
            if os.path.isfile(self.options["log-file"]):
                shutil.copy(self.options["log-file"], self.options["log-file"] + '.old')
            if os.path.isfile(self.options["log-file"]) \
               or not os.path.exists(self.options["log-file"]):
                open(self.options["log-file"], 'w').close() # Truncate it
                os.chmod(self.options["log-file"], 0o600)
        else:
            self.options["log-file"] = "/dev/null"

        pager = self.options.get("pager")
        if pager is None or not cmd_var_is_valid(pager):
            pager = os.environ.get("PAGER")
            if pager is None or not cmd_var_is_valid(pager):
                pager = "cat"

        pager_basename = os.path.basename(portage.util.shlex_split(pager)[0])
        if pager_basename == "less":
            less_opts = self.options.get("less-opts")
            if less_opts is not None and less_opts.strip():
                pager += " " + less_opts

        if pager_basename == "cat":
            pager = ""
        else:
            pager = " | " + pager

        #
        # Build list of extant configs
        #

        for path in config_paths:
            path = portage.normalize_path(
                 os.path.join(config_root, path.lstrip(os.sep)))
            try:
                mymode = os.stat(path).st_mode
            except OSError:
                continue
            basename = "*"
            find_opts = "-name '.*' -type d -prune -o"
            if not stat.S_ISDIR(mymode):
                path, basename = os.path.split(path)
                find_opts = "-maxdepth 1"

            with os.popen(FIND_EXTANT_CONFIGS %
                (path, find_opts, basename)) as proc:
                confs += self.massage(proc.readlines())

        if self.options['use-rcs'] == 'yes':
            for rcs_util in ("rcs", "ci", "co", "rcsmerge"):
                if not find_binary(rcs_util):
                    print('dispatch-conf: Error finding all RCS utils and " + \
                        "use-rcs=yes in config; fatal', file=sys.stderr)
                    return False


        # config file freezing support
        frozen_files = set(self.options.get("frozen-files", "").split())
        auto_zapped = []
        protect_obj = portage.util.ConfigProtect(
            config_root, config_paths,
            portage.util.shlex_split(
            portage.settings.get('CONFIG_PROTECT_MASK', '')))

        def diff(file1, file2):
            return diffstatusoutput(DIFF_CONTENTS, file1, file2)

        #
        # Remove new configs identical to current
        #                  and
        # Auto-replace configs a) whose differences are simply CVS interpolations,
        #                  or  b) whose differences are simply ws or comments,
        #                  or  c) in paths now unprotected by CONFIG_PROTECT_MASK,
        #

        def f (conf):
            mrgconf = re.sub(r'\._cfg', '._mrg', conf['new'])
            archive = os.path.join(self.options['archive-dir'], conf['current'].lstrip('/'))
            if self.options['use-rcs'] == 'yes':
                mrgfail = portage.dispatch_conf.rcs_archive(archive, conf['current'], conf['new'], mrgconf)
            else:
                mrgfail = portage.dispatch_conf.file_archive(archive, conf['current'], conf['new'], mrgconf)
            if os.path.exists(archive + '.dist'):
                unmodified = len(diff(conf['current'], archive + '.dist')[1]) == 0
            else:
                unmodified = 0
            if os.path.exists(mrgconf):
                if mrgfail or len(diff(conf['new'], mrgconf)[1]) == 0:
                    os.unlink(mrgconf)
                    newconf = conf['new']
                else:
                    newconf = mrgconf
            else:
                newconf = conf['new']

            if newconf == mrgconf and \
                self.options.get('ignore-previously-merged') != 'yes' and \
                os.path.exists(archive+'.dist') and \
                len(diff(archive+'.dist', conf['new'])[1]) == 0:
                # The current update is identical to the archived .dist
                # version that has previously been merged.
                os.unlink(mrgconf)
                newconf = conf['new']

            mystatus, myoutput = diff(conf['current'], newconf)
            myoutput_len = len(myoutput)
            same_file = 0 == myoutput_len
            if mystatus >> 8 == 2:
                # Binary files differ
                same_cvs = False
                same_wsc = False
            else:
                # Extract all the normal diff lines (ignore the headers).
                mylines = re.findall('^[+-][^\n+-].*$', myoutput, re.MULTILINE)

                # Filter out all the cvs headers
                cvs_header = re.compile('# [$]Header:')
                cvs_lines = list(filter(cvs_header.search, mylines))
                same_cvs = len(mylines) == len(cvs_lines)

                # Filter out comments and whitespace-only changes.
                # Note: be nice to also ignore lines that only differ in whitespace...
                wsc_lines = []
                for x in ['^[-+]\s*#', '^[-+]\s*$']:
                   wsc_lines += list(filter(re.compile(x).match, mylines))
                same_wsc = len(mylines) == len(wsc_lines)

            # Do options permit?
            same_cvs = same_cvs and self.options['replace-cvs'] == 'yes'
            same_wsc = same_wsc and self.options['replace-wscomments'] == 'yes'
            unmodified = unmodified and self.options['replace-unmodified'] == 'yes'

            if same_file:
                os.unlink (conf ['new'])
                self.post_process(conf['current'])
                if os.path.exists(mrgconf):
                    os.unlink(mrgconf)
                return False
            elif conf['current'] in frozen_files:
                """Frozen files are automatically zapped. The new config has
                already been archived with a .new suffix.  When zapped, it is
                left with the .new suffix (post_process is skipped), since it
                hasn't been merged into the current config."""
                auto_zapped.append(conf['current'])
                os.unlink(conf['new'])
                try:
                    os.unlink(mrgconf)
                except OSError:
                    pass
                return False
            elif unmodified or same_cvs or same_wsc or \
                not protect_obj.isprotected(conf['current']):
                self.replace(newconf, conf['current'])
                self.post_process(conf['current'])
                if newconf == mrgconf:
                    os.unlink(conf['new'])
                elif os.path.exists(mrgconf):
                    os.unlink(mrgconf)
                return False
            else:
                return True

        confs = [x for x in confs if f(x)]

        #
        # Interactively process remaining
        #

        valid_input = "qhtnmlezu"

        for conf in confs:
            count = count + 1

            newconf = conf['new']
            mrgconf = re.sub(r'\._cfg', '._mrg', newconf)
            if os.path.exists(mrgconf):
                newconf = mrgconf
            show_new_diff = 0

            while 1:
                clear_screen()
                if show_new_diff:
                    cmd = self.options['diff'] % (conf['new'], mrgconf)
                    cmd += pager
                    spawn_shell(cmd)
                    show_new_diff = 0
                else:
                    cmd = self.options['diff'] % (conf['current'], newconf)
                    cmd += pager
                    spawn_shell(cmd)

                print()
                print('>> (%i of %i) -- %s' % (count, len(confs), conf ['current']))
                print('>> q quit, h help, n next, e edit-new, z zap-new, u use-new\n   m merge, t toggle-merge, l look-merge: ', end=' ')

                # In some cases getch() will return some spurious characters
                # that do not represent valid input. If we don't validate the
                # input then the spurious characters can cause us to jump
                # back into the above "diff" command immediatly after the user
                # has exited it (which can be quite confusing and gives an
                # "out of control" feeling).
                while True:
                    c = getch()
                    if c in valid_input:
                        sys.stdout.write('\n')
                        sys.stdout.flush()
                        break

                if c == 'q':
                    sys.exit (0)
                if c == 'h':
                    self.do_help ()
                    continue
                elif c == 't':
                    if newconf == mrgconf:
                        newconf = conf['new']
                    elif os.path.exists(mrgconf):
                        newconf = mrgconf
                    continue
                elif c == 'n':
                    break
                elif c == 'm':
                    merged = SCRATCH_DIR+"/"+os.path.basename(conf['current'])
                    print()
                    ret = os.system (self.options['merge'] % (merged, conf ['current'], newconf))
                    ret = os.WEXITSTATUS(ret)
                    if ret < 2:
                        ret = 0
                    if ret:
                        print("Failure running 'merge' command")
                        continue
                    shutil.copyfile(merged, mrgconf)
                    os.remove(merged)
                    mystat = os.lstat(conf['new'])
                    os.chmod(mrgconf, mystat[ST_MODE])
                    os.chown(mrgconf, mystat[ST_UID], mystat[ST_GID])
                    newconf = mrgconf
                    continue
                elif c == 'l':
                    show_new_diff = 1
                    continue
                elif c == 'e':
                    if 'EDITOR' not in os.environ:
                        os.environ['EDITOR']='nano'
                    os.system(os.environ['EDITOR'] + ' ' + newconf)
                    continue
                elif c == 'z':
                    os.unlink(conf['new'])
                    if os.path.exists(mrgconf):
                        os.unlink(mrgconf)
                    break
                elif c == 'u':
                    self.replace(newconf, conf ['current'])
                    self.post_process(conf['current'])
                    if newconf == mrgconf:
                        os.unlink(conf['new'])
                    elif os.path.exists(mrgconf):
                        os.unlink(mrgconf)
                    break
                else:
                    raise AssertionError("Invalid Input: %s" % c)

        if auto_zapped:
            print()
            print(" One or more updates are frozen and have been automatically zapped:")
            print()
            for frozen in auto_zapped:
                print("  * '%s'" % frozen)
            print()

    def replace (self, newconf, curconf):
        """Replace current config with the new/merged version.  Also logs
        the diff of what changed into the configured log file."""
        os.system((DIFF_CONTENTS % (curconf, newconf)) + '>>' + self.options["log-file"])
        try:
            os.rename(newconf, curconf)
        except (IOError, os.error) as why:
            print('dispatch-conf: Error renaming %s to %s: %s; fatal' % \
                  (newconf, curconf, str(why)), file=sys.stderr)


    def post_process(self, curconf):
        archive = os.path.join(self.options['archive-dir'], curconf.lstrip('/'))
        if self.options['use-rcs'] == 'yes':
            portage.dispatch_conf.rcs_archive_post_process(archive)
        else:
            portage.dispatch_conf.file_archive_post_process(archive)


    def massage (self, newconfigs):
        """Sort, rstrip, remove old versions, break into triad hash.

        Triad is dictionary of current (/etc/make.conf), new (/etc/._cfg0003_make.conf)
        and dir (/etc).

        We keep ._cfg0002_conf over ._cfg0001_conf and ._cfg0000_conf.
        """
        h = {}
        configs = []
        newconfigs.sort ()

        for nconf in newconfigs:
            nconf = nconf.rstrip ()
            conf  = re.sub (r'\._cfg\d+_', '', nconf)
            dirname   = os.path.dirname(nconf)
            conf_map  = {
                'current' : conf,
                'dir'     : dirname,
                'new'     : nconf,
            }

            if conf in h:
                mrgconf = re.sub(r'\._cfg', '._mrg', h[conf]['new'])
                if os.path.exists(mrgconf):
                    os.unlink(mrgconf)
                os.unlink(h[conf]['new'])
                h[conf].update(conf_map)
            else:
                h[conf] = conf_map
                configs.append(conf_map)

        return configs


    def do_help (self):
        print()
        print()

        print('  u -- update current config with new config and continue')
        print('  z -- zap (delete) new config and continue')
        print('  n -- skip to next config, leave all intact')
        print('  e -- edit new config')
        print('  m -- interactively merge current and new configs')
        print('  l -- look at diff between pre-merged and merged configs')
        print('  t -- toggle new config between merged and pre-merged state')
        print('  h -- this screen')
        print('  q -- quit')

        print(); print('press any key to return to diff...', end=' ')

        getch ()


def getch ():
    # from ASPN - Danny Yoo
    #
    import tty, termios

    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    try:
        tty.setraw(sys.stdin.fileno())
        ch = sys.stdin.read(1)
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
    return ch

def clear_screen():
    try:
        import curses
        try:
            curses.setupterm()
            sys.stdout.write(_unicode_decode(curses.tigetstr("clear")))
            sys.stdout.flush()
            return
        except curses.error:
            pass
    except ImportError:
        pass
    os.system("clear 2>/dev/null")

shell = os.environ.get("SHELL")
if not shell or not os.access(shell, os.EX_OK):
    shell = find_binary("sh")

def spawn_shell(cmd):
    if shell:
        sys.__stdout__.flush()
        sys.__stderr__.flush()
        spawn([shell, "-c", cmd], env=os.environ,
            fd_pipes = {  0 : portage._get_stdin().fileno(),
                          1 : sys.__stdout__.fileno(),
                          2 : sys.__stderr__.fileno()})
    else:
        os.system(cmd)

def usage(argv):
    print('dispatch-conf: sane configuration file update\n')
    print('Usage: dispatch-conf [config dirs]\n')
    print('See the dispatch-conf(1) man page for more details')
    sys.exit(os.EX_OK)

for x in sys.argv:
    if x in ('-h', '--help'):
        usage(sys.argv)
    elif x in ('--version'):
        print("Portage", portage.VERSION)
        sys.exit(os.EX_OK)

# run
d = dispatch ()

if len(sys.argv) > 1:
    # for testing
    d.grind(sys.argv[1:])
else:
    d.grind(portage.util.shlex_split(
        portage.settings.get('CONFIG_PROTECT', '')))
