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

#
# archive-conf -- save off a config file in the dispatch-conf archive dir
#
#  Written by Wayne Davison <gentoo@blorf.net> with code snagged from
#  Jeremy Wohl's dispatch-conf script and the portage chkcontents script.
#

from __future__ import print_function

import 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__))), "lib"))
import portage
portage._internal_caller = True

import portage.dispatch_conf
from portage import os
from portage.checksum import perform_md5

FIND_EXTANT_CONTENTS  = "find %s -name CONTENTS"

MANDATORY_OPTS  = [ 'archive-dir' ]

def archive_conf():
    args = []
    content_files = []
    md5_match_hash = {}

    options = portage.dispatch_conf.read_config(MANDATORY_OPTS)

    for conf in sys.argv[1:]:
        if not os.path.isabs(conf):
            conf = os.path.abspath(conf)
        args += [ conf ]
        md5_match_hash[conf] = ''

    # Find all the CONTENT files in VDB_PATH.
    with os.popen(FIND_EXTANT_CONTENTS % (os.path.join(portage.settings['EROOT'], portage.VDB_PATH))) as f:
	    content_files += f.readlines()

    # Search for the saved md5 checksum of all the specified config files
    # and see if the current file is unmodified or not.
    try:
        todo_cnt = len(args)
        for filename in content_files:
            filename = filename.rstrip()
            try:
                contents = open(filename, "r")
            except IOError as e:
                print('archive-conf: Unable to open %s: %s' % (filename, e), file=sys.stderr)
                sys.exit(1)
            lines = contents.readlines()
            for line in lines:
                items = line.split()
                if items[0] == 'obj':
                    for conf in args:
                        if items[1] == conf:
                            stored = items[2].lower()
                            real = perform_md5(conf).lower()
                            if stored == real:
                                md5_match_hash[conf] = conf
                            todo_cnt -= 1
                            if todo_cnt == 0:
                                raise StopIteration()
    except StopIteration:
        pass

    for conf in args:
        archive = os.path.join(options['archive-dir'], conf.lstrip('/'))
        if options['use-rcs'] == 'yes':
            portage.dispatch_conf.rcs_archive(archive, conf, md5_match_hash[conf], '')
            if md5_match_hash[conf]:
                portage.dispatch_conf.rcs_archive_post_process(archive)
        else:
            portage.dispatch_conf.file_archive(archive, conf, md5_match_hash[conf], '')
            if md5_match_hash[conf]:
                portage.dispatch_conf.file_archive_post_process(archive)

# run
if len(sys.argv) > 1:
    archive_conf()
else:
    print('Usage: archive-conf /CONFIG/FILE [/CONFIG/FILE...]', file=sys.stderr)
