"""
decode a single binary frame
"""

from __future__ import print_function

import argparse
import json

from satnogsdecoders import decoder
from satnogsdecoders.decoder import kaitai_to_dict


def decode_frame_to_fields(decoder_name: str, raw_frame: bytes):
    """
    Decode raw frames and return fields as specified by the
    fields definition in 'doc'.
    """

    decoder_class = getattr(decoder, decoder_name.capitalize())
    frame = decoder_class.from_bytes(raw_frame)

    return decoder.get_fields(frame, empty=False)


def decode_frame_to_dict(decoder_name: str, raw_frame: bytes):
    """
    Decode raw frames into nested dicts, as specified by the
    kaitai struct itself.
    """
    decoder_class = getattr(decoder, decoder_name.capitalize())
    frame = decoder_class.from_bytes(raw_frame)

    return kaitai_to_dict(frame)


def decode_frame(decoder_name: str, raw_frame: bytes):
    """
    Deprecated.
    Use either `decode_frame_to_dict` or `decode_frame_to_fields` to specify
    more precisely the expected response.
    """
    return decode_frame_to_fields(decoder_name, raw_frame)


def main():
    """
    main entry point
    """

    parser = argparse.ArgumentParser(
        description='Decode a raw frame with the selected decoder '
        '(generated by Kaitai) and print its json representation, '
        'either of the telemetry frame directly, or the transformed '
        'result based on the fields specified in the struct docstring.')
    parser.add_argument('decoder_name',
                        type=str,
                        help='name of the decoder (e.g. siriussat)')
    parser.add_argument('raw_frame_file',
                        type=str,
                        help='Path to the file containing the raw frame')
    parser.add_argument('--raw-frame',
                        action='store_true',
                        help='Show the full decoded frame. '
                        'If not selected (default), show only selected fields '
                        'as specified by the docstring.')
    args = parser.parse_args()

    # Load the raw frame
    with open(args.raw_frame_file, 'rb') as rawfile:
        raw_frame = rawfile.read()

    if args.raw_frame:
        data = decode_frame_to_dict(args.decoder_name, raw_frame)
    else:
        data = decode_frame_to_fields(args.decoder_name, raw_frame)

    print(json.dumps(data, indent=4, sort_keys=False))
