#!/usr/bin/env python3
#
# SPDX-License-Identifier: GPL-2.0-only
#

import os
import sys
import shutil
import errno
import time

def mkdir(d):
    try:
        os.makedirs(d)
    except OSError as e:
        if e.errno != errno.EEXIST:
            raise e

# extract the hash from past the last colon to last underscore
def extract_sha(filename):
    return filename.split(':')[7].split('_')[0]

# get all files in a directory, extract hash and make
# a map from hash to list of file with that hash
def map_sha_to_files(dir_, prefix, sha_map):
    sstate_prefix_path = dir_ + '/' + prefix + '/'
    sstate_files = os.listdir(sstate_prefix_path)
    for f in sstate_files:
        try:
            sha = extract_sha(f)
            if sha not in sha_map:
                sha_map[sha] = []
            sha_map[sha].append(sstate_prefix_path + f)
        except IndexError:
            continue

# given a prefix build a map of hash to list of files
def build_sha_cache(prefix):
    sha_map = {}

    sstate_dir = sys.argv[2]
    map_sha_to_files(sstate_dir, prefix, sha_map)

    native_sstate_dir = sys.argv[2] + '/' + sys.argv[4]
    map_sha_to_files(native_sstate_dir, prefix, sha_map)

    return sha_map

if len(sys.argv) < 5:
    print("Incorrect number of arguments specified")
    print("syntax: gen-lockedsig-cache <locked-sigs.inc> <input-cachedir> <output-cachedir> <nativelsbstring> [filterfile]")
    sys.exit(1)

filterlist = []
if len(sys.argv) > 5:
    print('Reading filter file %s' % sys.argv[5])
    with open(sys.argv[5]) as f:
        for l in f.readlines():
            if ":" in l:
                filterlist.append(l.rstrip())

print('Reading %s' % sys.argv[1])
sigs = []
with open(sys.argv[1]) as f:
    for l in f.readlines():
        if ":" in l:
            task, sig = l.split()[0].rsplit(':', 1)
            if filterlist and not task in filterlist:
                print('Filtering out %s' % task)
            else:
                sigs.append(sig)

print('Gathering file list')
start_time = time.perf_counter()
files = set()
sstate_content_cache = {}
for s in sigs:
    prefix = s[:2]
    if prefix not in sstate_content_cache:
        sstate_content_cache[prefix] = build_sha_cache(prefix)

    for f in sstate_content_cache[prefix][s]:
        files.add(f)

elapsed = time.perf_counter() - start_time
print("Gathering file list took %.1fs" % elapsed)

print('Processing files')
for f in files:
    sys.stdout.write('Processing %s... ' % f)
    _, ext = os.path.splitext(f)
    if not ext in ['.tgz', '.siginfo', '.sig']:
        # Most likely a temp file, skip it
        print('skipping')
        continue
    dst = os.path.join(sys.argv[3], os.path.relpath(f, sys.argv[2]))
    destdir = os.path.dirname(dst)
    mkdir(destdir)

    src = os.path.realpath(f)
    if os.path.exists(dst):
        os.remove(dst)
    if (os.stat(src).st_dev == os.stat(destdir).st_dev):
        print('linking')
        try:
            os.link(src, dst)
        except OSError as e:
            print('hard linking failed, copying')
            shutil.copyfile(src, dst)
    else:
        print('copying')
        shutil.copyfile(src, dst)

print('Done!')
