#!/usr/bin/env python3
#
# cace_datasheet_upload.py
#
# Send newly-created challenge datasheet and associated
# design files (testbench schematics and netlists) to
# the  marketplace server for storage.
#

import os
import json
import re
import sys
import requests
import subprocess

import file_compressor
import file_request_hash

import config

"""
 standalone script.
 Makes rest calls to marketplace REST server to save datasheet
 and associated file(s).  Request hash is generated so the two
 requests can be associated on the server side.  This action
 has no other side effects.
"""

mktp_server_url = config.mktp_server_url

# Make request to server sending json passed in.
def send_doc(doc):
    result = requests.post(mktp_server_url + '/cace/save_datasheet', json=doc)
    print('send_doc', result.status_code)

# Pure HTTP post here.  Add the file to files object and the hash/filename
# to the data params.
def send_file(hash, file, file_name):
    files = {'file': file.getvalue()}
    data = {'request-hash': hash, 'file-name': file_name}
    result = requests.post(mktp_server_url + '/cace/save_files', files=files, data=data)
    print('send_file', result.status_code)


if __name__ == '__main__':

    # Divide up command line into options and arguments
    options = []
    arguments = []
    for item in sys.argv[1:]:
        if item.find('-', 0) == 0:
            options.append(item)
        else:
            arguments.append(item)

    # There should be two arguments passed to the script.  One is
    # the path and filename of the datasheet JSON file, and the
    # other a path to the location of testbenches (netlists and/or
    # schematics).  If there is only one argument, then datasheet_filepath
    # is assumed to be in the same path as netlist_filepath.

    datasheet_filepath = []
    netlist_filepath = []

    for argval in arguments:
        if os.path.isfile(argval):
            datasheet_filepath = argval
        elif os.path.isdir(argval):
            netlist_filepath = argval
        elif os.path.splitext(argval)[1] == '':
            argname = argval + '.json'
            if os.path.isfile(argval):
                datasheet_filepath = argname

    if not datasheet_filepath:
        # Check for JSON file 'project.json' in the netlist filepath directory
        # or the directory above it.
        if netlist_filepath:
            argtry = netlist_filepath + '/project.json'
            if os.path.isfile(argtry):
                datasheet_filepath = argtry
            else:
                argtry = os.path.split(netlist_filepath)[0] + '/project.json'
                if os.path.isfile(argtry):
                    datasheet_filepath = argtry

        # Legacy behavior support
        if not os.path.isfile(datasheet_filepath):
            # Check for JSON file with same name as netlist filepath,
            # but with a .json extension, in the netlist filepath directory
            # or the directory above it.
            if netlist_filepath:
                argtry = netlist_filepath + '/' + os.path.basename(netlist_filepath) + '.json'
                if os.path.isfile(argtry):
                    datasheet_filepath = argtry
                else:
                    argtry = os.path.split(netlist_filepath)[0] + '/' + os.path.basename(netlist_filepath) + '.json'
                    if os.path.isfile(argtry):
                        datasheet_filepath = argtry

    if not datasheet_filepath:
        print('Error:  No datasheet JSON file specified.\n')
        sys.exit(1)

    if not os.path.isfile(datasheet_filepath):
        print('Error:  No datasheet JSON file ' + datasheet_filepath + ' found.\n')
        sys.exit(1)

    # Technically okay to have null netlist_filepath, but unlikely,
    # so flag a warning.

    if not netlist_filepath:
        print('Warning: No netlist filepath given.  No files will be '
		+ 'transmitted with the datasheet.\n')

    dsheet = {}
    with open(datasheet_filepath, 'r') as user_doc_file:
        docinfo = json.load(user_doc_file)
        dsheet = docinfo['data-sheet']
        try:
            name = dsheet['ip-name']
        except KeyError:
            datasheet_file = os.path.split(datasheet_filepath)[1]
            name = os.path.splitext(datasheet_file)[0]
            dsheet['ip-name'] = name

    # Behavior starting 4/27/2017:  the UID is required to be a
    # numeric value, but the datasheet upload is generally being
    # done as user admin from the remote CACE host, and admin has
    # no official UID number.  So always attach ID 9999 to datasheet
    # uploads.

    if 'UID' in docinfo:
        uid = docinfo['UID']
    else:
        uid = 9999
        docinfo['UID'] = uid

    # Get a request hash and add it to the JSON document
    rhash, timestamp = file_request_hash.get_hash(name)
    docinfo['request-hash'] = rhash

    # Put the current git system state into the target directory
    # prior to tarballing
    if os.path.isfile('/ef/.ef-version'):
        with open('/ef/.ef-version', 'r') as f:
            ef_version = f.read().rstrip()
        docinfo['ef-version'] = ef_version

    # Now send the datasheet
    if '-test' in options:
        print("Test:  running send_doc( <docinfo> )\n")
        print("       with docinfo['UID'] = " + uid + "\n")
    else:
        send_doc(docinfo)

    # Send the merged JSON file and the tarballed design file directory
    # to the marketplace server for storage.

    if netlist_filepath:
        # Use the version below to ignore the 'spi' directory.  However, it may
        # be the intention of the challenge creator to seed the challenge with
        # an example.  This is normally not the case.  So use '-include' option
        # to avoid excluding the 'spi' folder contents.
        if '-includeall' in options:
            print('Including netlist/schematic and simulation files in project folder.')
            tar = file_compressor.tar_directory_contents(netlist_filepath,
			exclude=['elec/\.java', 'elec/electric\.log', name + '\.log',
			'.*\.raw', 'ngspice/run/\.allwaves'])
        elif '-include' in options:
            print('Including netlist/schematic files in project folder.')
            tar = file_compressor.tar_directory_contents(netlist_filepath,
			exclude=['ngspice', 'elec/\.java', 'elec/electric\.log',
			name + '\.log'])
        else:
            print('Excluding netlist/schematic and simulation files in project folder.')
            tar = file_compressor.tar_directory_contents(netlist_filepath,
			exclude=['spi', 'ngspice', 'elec/\.java', 'mag', 'elec/electric\.log',
			'elec/' + name + '\.delib/' + name + '\.sch', name + '\.log'])
        tarballname = name + '.tar.gz'

        # Now send the netlist file tarball
        if '-test' in options:
            print('Test:  running send_file(' + rhash + ' <tarball> ' + tarballname + ')')
            print('Saving tarball locally as ' + tarballname)
            file_compressor.tar_directory_contents_to_file(netlist_filepath,
			tarballname, exclude=['spi', 'ngspice', 'elec/\.java', 'mag',
			'elec/electric\.log', 'elec/' + name + '\.delib/' + name + '\.sch',
			name + '\.log'])
        else:
            send_file(rhash, tar, tarballname)

