#!/usr/bin/env python

import argparse
import bz2
import csv
import hashlib
import os
import shlex
import sqlite3
import subprocess
import tempfile
from pathlib import Path


def parseArgs():
    parser = argparse.ArgumentParser()
    parser.add_argument('csv_file', type=str,
                        help='File containing cache files to compile '
                             'in the format of: filename, args')
    parser.add_argument('--num-cus', default=4, type=int,
                        help='Number of CUs in simulated GPU')
    parser.add_argument('--gfx-version', default='gfx801',
                        choices=['gfx801', 'gfx803'],
                        help='gfx version of simulated GPU')

    return parser.parse_args()


def getDb(options):
    db_name = f'{options.gfx_version}_{options.num_cus}.ukdb'
    db_path = '/root/.cache/miopen/2.9.0/'

    full_db_path = os.path.join(db_path, db_name)
    # Should create file if it doesn't exist
    # Does assume db_path exists, which it should in the Docker image
    con = sqlite3.connect(full_db_path)

    cur = con.cursor()

    # Ripped from src/include/miopen/kern_db.hpp
    cur.execute('''CREATE TABLE IF NOT EXISTS kern_db (
                        id INTEGER PRIMARY KEY ASC,
                        kernel_name TEXT NOT NULL,
                        kernel_args TEXT NOT NULL,
                        kernel_blob BLOB NOT NULL,
                        kernel_hash TEXT NOT NULL,
                        uncompressed_size INT NOT NULL);''')
    cur.execute('''CREATE UNIQUE INDEX IF NOT EXISTS
                    idx_kern_db ON kern_db (kernel_name, kernel_args);''')

    return con


def insertFiles(con, options):
    miopen_kern_path = '/MIOpen/src/kernels'

    extra_args = {'gfx801': '-Wno-everything -Xclang '
                            '-target-feature -Xclang +code-object-v3',
                  'gfx803': '-Wno-everything -Xclang '
                            '-target-feature -Xclang +code-object-v3'}

    with tempfile.TemporaryDirectory() as tmpdir:
        with open(options.csv_file) as csvfile:
            reader = csv.reader(csvfile)
            for row in reader:
                miopen_kern = row[0]
                miopen_kern_full = os.path.join(miopen_kern_path, miopen_kern)
                # We want to manually add the gfx version
                # Additionally, everything after the gfx version isn't
                # used in the database
                # Explicitly add the leading space because that's used
                # in the database
                args = (f' {row[1].split("-mcpu")[0].strip()} '
                        f'-mcpu={options.gfx_version}')

                # Hash to generate unique output files
                file_hash = hashlib.md5(args.encode('utf-8')).hexdigest()
                outfile = f'{miopen_kern}-{file_hash}.o'
                full_outfile = os.path.join(tmpdir, outfile)

                # Compile the kernel
                cmd_str = (f'/opt/rocm/bin/clang-ocl {args} '
                           f'{extra_args[options.gfx_version]} '
                           f'{miopen_kern_full} -o {full_outfile}')
                cmd_args = shlex.split(cmd_str)
                subprocess.run(cmd_args, check=True)

                # Get other params needed for db
                uncompressed_file = open(full_outfile, 'rb').read()
                uncompressed_size = Path(full_outfile).stat().st_size
                uncompressed_hash = hashlib.md5(uncompressed_file).hexdigest()
                compressed_blob = bz2.compress(uncompressed_file)

                cur = con.cursor()
                cur.execute('''INSERT OR IGNORE INTO kern_db
                               (kernel_name, kernel_args, kernel_blob, kernel_hash, uncompressed_size)
                               VALUES(?, ?, ?, ?, ?)''',
                            (f'{miopen_kern}.o', args, compressed_blob,
                                uncompressed_hash, uncompressed_size))


def main():

    args = parseArgs()

    con = getDb(args)

    insertFiles(con, args)

    con.commit()
    con.close()


if __name__ == '__main__':
    main()
