#!/usr/bin/env python3
# GStreamer
# Copyright (C) 2020 Matthew Waters <matthew@centricular.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#

import binascii
import sys
import os
import argparse

autogenerated_notice = """/*
 * This file is autogenerated by bin2array.py
 */
"""

def make_sublist_group (lst: list, grp: int) -> list:
    """
    Group list elements into sublists.
    make_sublist_group([1, 2, 3, 4, 5, 6, 7], 3) = [[1, 2, 3], [4, 5, 6], 7]
    """
    return [lst[i:i+grp] for i in range(0, len(lst), grp)]

def generate_c_array_data (bindata: bytes,
                           element_prefix: str,
                           element_size: int,
                           element_suffix: str,
                           newline_value: str,
                           newline_after: int,
                           element_separator: str) -> str:
    """
    Generate the contents of a C array as a hex string
    e.g:
    0x10, 0x20, 0x30, 0x40,
    0x50, 0x60, 0x70, 0x80,
    """
    hexstr = binascii.hexlify(bindata).decode("UTF-8")
    array = []
    for i in range(0, len(hexstr), 2 * element_size):
        array += [element_prefix + hexstr[i:i + 2 * element_size] + element_suffix]

    if newline_after:
        array = make_sublist_group(array, newline_after)
    else:
        array = [array,]

    return newline_value.join([element_separator.join(e) + element_separator for e in array])

def decorate_c_array_data (hexdata: str,
                           var_name: str,
                           var_type: str,
                           newline_value: str):
    """
    Place @hexdata into a valid C array named @var_name of C type @var_type.
    """
    ret = var_type + " " + var_name + "[] = {" + newline_value
    ret += hexdata + newline_value
    ret += "};" + newline_value
    return ret

def main(args):
    parser = argparse.ArgumentParser(description='Convert binary file to C-style array initializer.')
    parser.add_argument("-i", "--input", help="the file to be converted")
    parser.add_argument("--output", help="c source file location")
    parser.add_argument("--header-output", help="c header file location")
    parser.add_argument("--linebreak", type=int, help="add linebreak after every N element")
    parser.add_argument("--linebreak-value", default="\n", help="use what sequence to break lines, defaults to \"\\n\"")
    parser.add_argument("--separator", default=", ", help="use what to separate elements, defaults to \", \"")
    parser.add_argument("--array-name", default="array_data", help="name of the resulting array")
    parser.add_argument("--element-type", default="char", help="C type for the array")
    parser.add_argument("--element-size", type=int, default=1, help="how many bytes per element")
    parser.add_argument("--element-prefix", default="0x", help="string to be added to the head of element, defaults to \"0x\"")
    parser.add_argument("--element-suffix", default="", help="string to be added to the tail of element, defaults to none")
    parser.add_argument("--c-include", help="header to include")
    args = parser.parse_args(args)

    with open(args.input, 'rb') as f:
        file_content = f.read()

    # don't deal with unaligned content
    assert len(file_content) % args.element_size == 0

    # get a relative path from the source file to the header to use in an #include
    source_to_header = os.path.relpath (os.path.dirname (args.header_output),
                                        os.path.dirname (args.output))

    ret = autogenerated_notice
    ret += "#include \""
    ret += os.path.join (source_to_header,
                         os.path.basename (args.header_output))
    ret += "\"" + args.linebreak_value

    arr_data = generate_c_array_data (file_content,
                                      args.element_prefix,
                                      args.element_size,
                                      args.element_suffix,
                                      args.linebreak_value,
                                      args.linebreak,
                                      args.separator)
    ret += decorate_c_array_data (arr_data,
                                  args.array_name,
                                  args.element_type,
                                  args.linebreak_value)

    with open (args.output, 'w') as f:
        f.write (ret)

    # write companion header
    with open(args.header_output, 'w') as f:
        f.write (autogenerated_notice)
        if args.c_include:
            f.write ("#include <" + args.c_include + ">" + args.linebreak_value)
        f.write ("extern " + args.element_type + " " + args.array_name + "[];" + args.linebreak_value)
        f.write ("#define " + args.array_name + "_size " + str(len(file_content) // args.element_size))

if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
