#!/usr/bin/env python3

import subprocess
import tempfile
import argparse
import os
import string
import sys
import shutil

quartus_cpf_template = """<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
<cof>
	<output_filename>${OUTPUT_FILENAME}</output_filename>
	<n_pages>1</n_pages>
	<width>1</width>
	<mode>14</mode>
	<sof_data>
		<user_name>Page_0</user_name>
		<page_flags>1</page_flags>
		<bit0>
			<sof_filename>${SOF_FILENAME}<compress_bitstream>1</compress_bitstream></sof_filename>
		</bit0>
	</sof_data>
	<version>10</version>
	<create_cvp_file>0</create_cvp_file>
	<create_hps_iocsr>0</create_hps_iocsr>
	<auto_create_rpd>0</auto_create_rpd>
	<rpd_little_endian>1</rpd_little_endian>
	<options>
		<map_file>1</map_file>
	</options>
	<MAX10_device_options>
		<por>0</por>
		<io_pullup>1</io_pullup>
		<config_from_cfm0_only>0</config_from_cfm0_only>
		<isp_source>0</isp_source>
		<verify_protect>0</verify_protect>
		<epof>0</epof>
		<ufm_source>2</ufm_source>
		<ufm_filepath>${KERNEL_FILENAME}</ufm_filepath>
	</MAX10_device_options>
	<advanced_options>
		<ignore_epcs_id_check>2</ignore_epcs_id_check>
		<ignore_condone_check>2</ignore_condone_check>
		<plc_adjustment>0</plc_adjustment>
		<post_chain_bitstream_pad_bytes>-1</post_chain_bitstream_pad_bytes>
		<post_device_bitstream_pad_bytes>-1</post_device_bitstream_pad_bytes>
		<bitslice_pre_padding>1</bitslice_pre_padding>
	</advanced_options>
</cof>
"""

# XXX Do we care about FileRevision, DefaultMfr, PartName? Do they need
# to be parameters? So far seems to work across 2 different boards, leave
# this alone for now.
quartus_pgm_template = """/* Quartus Prime Version 16.0.0 Build 211 04/27/2016 SJ Lite Edition */
JedecChain;
	FileRevision(JESD32A);
	DefaultMfr(6E);

	P ActionCode(Cfg)
		Device PartName(10M50DAF484ES) Path("${POF_DIR}/") File("${POF_FILE}") MfrSpec(OpMask(1));

ChainEnd;

AlteraBegin;
	ChainType(JTAG);
AlteraEnd;"""


def create_pof(input_sof, kernel_hex):
    """given an input CPU .sof file and a kernel binary, return a file-like
    object containing .pof data suitable for flashing onto the device"""

    t = string.Template(quartus_cpf_template)
    output_pof = tempfile.NamedTemporaryFile(suffix=".pof")

    input_sof = os.path.abspath(input_sof)
    kernel_hex = os.path.abspath(kernel_hex)

    # These tools are very stupid and freak out if the desired filename
    # extensions are used. The kernel image must have extension .hex

    with tempfile.NamedTemporaryFile(suffix=".cof") as temp_xml:

        xml = t.substitute(SOF_FILENAME=input_sof,
                           OUTPUT_FILENAME=output_pof.name,
                           KERNEL_FILENAME=kernel_hex)

        temp_xml.write(bytes(xml, 'UTF-8'))
        temp_xml.flush()

        cmd = ["quartus_cpf", "-c", temp_xml.name]
        try:
            subprocess.check_output(cmd)
        except subprocess.CalledProcessError as cpe:
            print(cpe.output.decode("UTF-8"))
            print("Failed to create POF file")
            sys.exit(1)

    return output_pof


def flash_kernel(device_id, input_sof, kernel_hex):
    pof_file = create_pof(input_sof, kernel_hex)

    with tempfile.NamedTemporaryFile(suffix=".cdf") as temp_cdf:
        dname, fname = os.path.split(pof_file.name)
        t = string.Template(quartus_pgm_template)
        cdf = t.substitute(POF_DIR=dname, POF_FILE=fname)
        temp_cdf.write(bytes(cdf, 'UTF-8'))
        temp_cdf.flush()
        cmd = ["quartus_pgm", "-c", device_id, temp_cdf.name]
        try:
            subprocess.check_output(cmd)
        except subprocess.CalledProcessError as cpe:
            print(cpe.output.decode("UTF-8"))
            print("Failed to flash image")
            sys.exit(1)
    pof_file.close()

def main():
    parser = argparse.ArgumentParser(description="Flash zephyr onto Altera boards")
    parser.add_argument("-s", "--sof",
            help=".sof file with Nios II CPU configuration")
    parser.add_argument("-k", "--kernel",
            help="Zephyr kernel image to place into UFM in Intel HEX format")
    parser.add_argument("-d", "--device",
            help="Remote device identifier / cable name. Default is "
                 "USB-BlasterII. Run jtagconfig -n if unsure.",
            default="USB-BlasterII")

    args = parser.parse_args()

    flash_kernel(args.device, args.sof, args.kernel)


if __name__ == "__main__":
    main()
