#!/usr/bin/python
# Copyright 1999-2013 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
pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
sys.path.insert(0, pym_path)
import portage
portage._internal_caller = True

import portage.dispatch_conf
from portage import os

FIND_EXTANT_CONTENTS  = "find %s -name CONTENTS"

MANDATORY_OPTS  = [ 'archive-dir' ]

try:
    import fchksum
    def perform_checksum(filename): return fchksum.fmd5t(filename)
except ImportError:
    import md5
    def md5_to_hex(md5sum):
        hexform = ""
        for ix in range(len(md5sum)):
            hexform = hexform + "%02x" % ord(md5sum[ix])
        return hexform.lower()

    def perform_checksum(filename):
        f = open(filename, 'rb')
        blocksize=32768
        data = f.read(blocksize)
        size = 0
        checksum = md5.new()
        while data:
            checksum.update(data)
            size = size + len(data)
            data = f.read(blocksize)
        return (md5_to_hex(checksum.digest()), size)

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_checksum(conf)[0].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)
