#!/usr/bin/python3
# -*- coding: utf-8 -*-

import argparse
import os
import shutil
import sys
import tarfile
import tempfile

parser = argparse.ArgumentParser(description='APK database merge script')
parser.add_argument('layers', help='Path to LXC layers to be merged', nargs=argparse.REMAINDER)

if len(sys.argv) < 2:
    parser.print_usage()
    sys.exit(1)
args = parser.parse_args()
layers = args.layers[::-1]

# /etc/apk/world
world = []
for layer in layers:
    try:
        with open(os.path.join(layer, 'etc/apk/world'), 'r') as f:
            for line in f:
                if line not in world:
                    world.append(line)
    except:
        continue
os.makedirs(os.path.join(layers[-1], 'etc/apk'), 0o755, True)
with open(os.path.join(layers[-1], 'etc/apk/world'), 'w') as f:
    f.writelines(world)
os.chown(os.path.join(layers[-1], 'etc'), 100000, 100000)
os.chown(os.path.join(layers[-1], 'etc/apk'), 100000, 100000)
os.chown(os.path.join(layers[-1], 'etc/apk/world'), 100000, 100000)

# /lib/apk/db/installed
installed = []
for layer in layers:
    try:
        with open(os.path.join(layer, 'lib/apk/db/installed'), 'r') as f:
            buffer = []
            for line in f:
                if line.startswith('C:'):
                    buffer = ''.join(buffer)
                    if buffer not in installed:
                        installed.append(buffer)
                    buffer = []
                buffer.append(line)
            buffer = ''.join(buffer)
            if buffer not in installed:
                installed.append(buffer)
    except:
        continue
os.makedirs(os.path.join(layers[-1], 'lib/apk/db'), 0o755, True)
with open(os.path.join(layers[-1], 'lib/apk/db/installed'), 'w') as f:
    f.writelines(installed)
os.chown(os.path.join(layers[-1], 'lib'), 100000, 100000)
os.chown(os.path.join(layers[-1], 'lib/apk'), 100000, 100000)
os.chown(os.path.join(layers[-1], 'lib/apk/db'), 100000, 100000)
os.chown(os.path.join(layers[-1], 'lib/apk/db/installed'), 100000, 100000)

# /lib/apk/db/scripts.tar
tmp_tar_path = tempfile.mkstemp()[1]
files_in_tar = []
with tarfile.open(tmp_tar_path, 'w:') as tmp_tar:
    for layer in layers:
        tar_path = os.path.join(layer, 'lib/apk/db/scripts.tar')
        if os.path.exists(tar_path):
            with tarfile.open(tar_path, 'r:') as tar:
                for member in tar.getmembers():
                    if member.name not in files_in_tar:
                        buffer = tar.extractfile(member)
                        tmp_tar.addfile(member, buffer)
                        files_in_tar.append(member.name)
if files_in_tar:
    shutil.move(tmp_tar_path, os.path.join(layers[-1], 'lib/apk/db/scripts.tar'))
    os.chown(os.path.join(layers[-1], 'lib/apk/db/scripts.tar'), 100000, 100000)
else:
    os.unlink(tmp_tar_path)

# /lib/apk/db/triggers
triggers = []
for layer in layers:
    try:
        with open(os.path.join(layer, 'lib/apk/db/triggers'), 'r') as f:
            for line in f:
                if line not in triggers:
                    triggers.append(line)
    except:
        continue
with open(os.path.join(layers[-1], 'lib/apk/db/triggers'), 'w') as f:
    f.writelines(triggers)
os.chown(os.path.join(layers[-1], 'lib/apk/db/triggers'), 100000, 100000)