#!/usr/bin/env python3
#
# cace_design_upload.py
#
# The purpose of this script is to package up the user
# design schematic and associated files and send them to
# the remote marketplace server, precipitating a launch
# of CACE to officially characterize the design.
#

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

import file_compressor
import file_request_hash
import local_uid_services

"""
 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
 causes the marketplace to run the official characterization
 on the CACE server.
"""

mktp_server_url = ""
cace_server_url = ""

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

# Cancel simulation (sent directly to CACE)
def send_cancel_doc(doc):
    result = requests.post(cace_server_url + '/cace/cancel_sims', json=doc)
    print('send_cancel_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/simulate_request_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 the design (netlist and/or
    # schematic).

    datasheet_filepath = []
    design_filepath = []

    for argval in arguments:
        if os.path.isfile(argval):
            datasheet_filepath = argval
        elif os.path.isdir(argval):
            design_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 current or parent directory
        if design_filepath:
            argtry = design_filepath + '/project.json'
            if os.path.isfile(argtry):
                datasheet_filepath = argtry
            else:
                argtry = os.path.split(design_filepath)[0] + '/project.json'
                if os.path.isfile(argtry):
                    datasheet_filepath = argtry

        if not os.path.isfile(datasheet_filepath):
            # Legacy behavior support:
            # 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 design_filepath:
                argtry = design_filepath + '/' + os.path.basename(design_filepath) + '.json'
                if os.path.isfile(argtry):
                    datasheet_filepath = argtry
                else:
                    argtry = os.path.split(design_filepath)[0] + '/' + os.path.basename(design_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)

    # Read the datasheet now.  Get the expected design name

    dsheet = {}
    print('Reading JSON datasheet ' + datasheet_filepath)
    with open(datasheet_filepath, 'r') as user_doc_file:
        docinfo = json.load(user_doc_file)
        dsheet = docinfo['data-sheet']
        name = dsheet['ip-name']

    # Get JSON file of settings if it exists.  It should be in the same
    # location as the JSON datasheet file (generated by cace.py)
    testmode = False
    force = False
    settings_filepath = os.path.split(datasheet_filepath)[0] + '/settings.json'
    if os.path.exists(settings_filepath):
        with open(settings_filepath, 'r') as user_settings_file:
            settings = json.load(user_settings_file)
            docinfo['settings'] = settings
            if 'submit-as-schematic' in settings:
                if settings['submit-as-schematic'] == True:
                    force = True
            if 'submit-test-mode' in settings:
                if settings['submit-test-mode'] == True:
                    testmode = True

    # Use of "-force" in the options overrides any settings from the JSON file.
    if '-force' in options:
        force = True

    if '-test' in options:
        testmode = True

    # Diagnostic
    if 'identifiers' in docinfo:
        print('Identifiers: ' + str(docinfo['identifiers']))

    if not design_filepath:
        print('Error:  No schematic or netlist directory given\n')
        sys.exit(1)
    else:
        # If design_filepath has a subdirectory "design", add that to
        # the path name.
        if os.path.isdir(design_filepath + '/spi'):
            spice_filepath = design_filepath + '/spi'
            filelist = os.listdir(spice_filepath)
        if os.path.isdir(design_filepath + '/elec'):
            if os.path.isdir(design_filepath + '/elec/' + name + '.delib'):
                schem_filepath = design_filepath + '/elec/' + name + '.delib'
                filelist.extend(os.listdir(schem_filepath))

        # To be valid, the filepath must contain either a .spi file with
        # the name of ip-name, or a .sch file with the name of ip-name.
        netlistname = name + '.spi'
        schemname = name + '.sch'
        if netlistname not in filelist and schemname not in filelist:
            print('Error:  Path ' + design_filepath + ' has no schematic '
			+ 'or netlist for design ' + name + '\n')
            sys.exit(1)

    # Add key 'project-folder' to the document, containing the path to the
    # JSON file.  This is used by the CACE to ensure that progress information
    # is passed to the correct folder, not relying on hard-coded home paths,
    # and allowing for copies of projects in different paths.

    foldername = os.path.split(datasheet_filepath)[0]
    docinfo['project-folder'] = foldername

    # Current expectation is to use UID (username).  If it is not in the
    # document, then add it here.

    if testmode:
        uid = {}
    else:
        if 'UID' not in docinfo:
            uid = local_uid_services.get_uid(os.environ['USER'])
        else:
            uid = docinfo['UID']

    if not uid or uid == 'null':
        uid = os.environ['USER']
    docinfo['UID'] = uid

    # Handle cancel requests
    if '-cancel' in options:
        # Read last message . . .
        if os.path.exists(design_filepath + '/ngspice/char/remote_status.json'):
            with open(design_filepath + '/ngspice/char/remote_status.json', 'r') as f:
                status = json.load(f)
            if 'hash' in status:
                docinfo['request-hash'] = status['hash']
                send_cancel_doc(docinfo)
            else:
                print('No hash value in status file, cannot cancel.')
        else:
            print('No status file found, cannot cancel.')
        sys.exit(0)

    # If settings specify that the submission should be forced to be schematic-only,
    # pass the setting to CACE as 'netlist-source' in the data-sheet record.
    if force:
        dsheet['netlist-source'] = 'schematic'

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

    rhash, timestamp = file_request_hash.get_hash(name)
    docinfo['request-hash'] = rhash
    print('request hash = ' + rhash + '\n')

    # Now send the document
    if testmode:
        print('Test:  running send_doc(docinfo)\n')
    else:
        send_doc(docinfo)

    # Send the tarballed design file directory to the marketplace server for storage.
    # Ignore the log file, which is meant for in-system diagnostics, not for storage.
    exclusions = [name + '\.log', '.*\.raw',
		'elec/\.java',
		'ngspice/run/\.allwaves']

    # If settings specify that the submission should be forced to be schematic-only,
    # then don't tarball the layout database files.
    if force:
        exclusions.append('mag/.*\.mag')
        exclusions.append('mag/.*\.ext')

    # Now send the netlist file tarball
    tarballname = name + '.tar.gz'
    if testmode:
        file_compressor.tar_directory_contents_to_file(design_filepath,
		tarballname, exclude=exclusions)
        os.rename(design_filepath + '/' + tarballname, tarballname)
        print('Test:  running send_file(' + rhash + ', <tarball>, ' + tarballname + ')\n')
    else:
        tar = file_compressor.tar_directory_contents(design_filepath,
		exclude=exclusions)
        send_file(rhash, tar, tarballname)

