import argparse


def convert_arg_line_to_args(arg_line):
    for arg in arg_line.split():
        if not arg.strip():
            continue
        yield arg


def load_args_from_file(path: str) -> argparse.Namespace:
    parser = argparse.ArgumentParser(description='BTS PyTorch implementation.', fromfile_prefix_chars='@')
    parser.convert_arg_line_to_args = convert_arg_line_to_args

    parser.add_argument('--model_name', type=str, help='model name', default='bts_nyu_v2')
    parser.add_argument('--encoder', type=str, help='type of encoder, vgg or desenet121_bts or densenet161_bts',
                        default='densenet161_bts')
    parser.add_argument('--data_path', type=str, help='path to the data', required=True)
    parser.add_argument('--filenames_file', type=str, help='path to the filenames text file', required=True)
    parser.add_argument('--filename_to_eval', type=str, help='path to the a specific file for online evaluation')
    parser.add_argument('--focal_to_eval', type=str, help='focal value of the specific file for online evaluation')
    parser.add_argument('--input_height', type=int, help='input height', default=480)
    parser.add_argument('--input_width', type=int, help='input width', default=640)
    parser.add_argument('--max_depth', type=float, help='maximum depth in estimation', default=80)
    parser.add_argument('--checkpoint_path', type=str, help='path to a specific checkpoint to load', default='')
    parser.add_argument('--dataset', type=str, help='dataset to train on, make3d or nyudepthv2', default='nyu')
    parser.add_argument('--do_kb_crop', help='if set, crop input images as kitti benchmark images', action='store_true')
    parser.add_argument('--upsample_kitti_for_wavelet', help='if set, upsample kitti images to 1280x384', action='store_true')
    parser.add_argument('--save_lpg', help='if set, save outputs from lpg layers', action='store_true')
    parser.add_argument('--bts_size', type=int,   help='initial num_filters in bts', default=512)
    parser.add_argument('--distributed', action='store_true')

    # Compression
    parser.add_argument('--quantize', type=str, help='if set, convolution layers will be quantized (none/soft/hard)', default="none")
    parser.add_argument('--weight_bits', type=int, help='number of quantization bits for the weights', default=8)
    parser.add_argument('--act_bits', type=int, help='number of quantization bits for the activations', default=4)
    parser.add_argument('--wavelet', help='if set, convolution layers will also be compressed using wavelet', action='store_true')
    parser.add_argument('--wavelet_from_checkpoint', help='if set, finetuning a wavelet model from quantized checkpoint', action='store_true')
    parser.add_argument('--wavelet_skip_reductions', help='if set, wont use wavelet on reduction layers', action='store_true')
    parser.add_argument('--wavelet_ignore_low_spatial_size', help='use wavelet as-is on alls spatial sizes', action='store_true')
    parser.add_argument('--wavelet_compression', type=float, help='factor of wavelet compression', default=0.25)
    parser.add_argument('--wavelet_levels', type=int, help='number of levels for wavelet transform', default=3)
    parser.add_argument('--wavelet_use_ste', help='use a straight through estimator when training a wavelet compressed network', action='store_true')

    arg_filename_with_prefix = '@' + path
    args = parser.parse_args([arg_filename_with_prefix])

    return args

