import argparse
import os

from genomelake import backend


def parse_args():
    parser = argparse.ArgumentParser(
        description='Generate arrays for memmapped extractors')
    parser.add_argument('input_file',
                        help='File to convert',
                        type=os.path.abspath)
    parser.add_argument('output_dir',
                        help='Output directory',
                        type=os.path.abspath)

    parser.add_argument('--filetype',
                        help='File type: bigwig / fasta / fragbed'
                             '(autodetect if not specified)')

    parser.add_argument('--mode',
                        help='Storage mode: numpy / bcolz (default)',
                        default='bcolz')

    parser.add_argument('--genome_file',
                        help='Genome size file for fragment BED')

    parser.add_argument('--max_fraglen',
                        help='Maximum fragment length for fragment BED',
                        type=int)

    args = parser.parse_args()

    if args.mode not in backend._array_writer:
        raise ValueError('Invalid mode specified: {}'.format(args.mode))

    # autodetect filetype
    if not args.filetype:
        ext2filetype = {
            '.bw': 'bigwig',
            '.bigwig': 'bigwig',
            '.fa': 'fasta',
            '.fasta': 'fasta',
        }

        _, ext = os.path.splitext(args.input_file)

        try:
            args.filetype = ext2filetype[ext]
        except KeyError:
            raise ValueError('Could not autodetect file type. '
                             'Please specify it using --filetype.')

    if args.filetype == 'fragbed':
        if args.genome_file is None:
            raise ValueError('--genome_file is required for fragbed files')
        if args.max_fraglen is None:
            raise ValueError('--max_fraglen is required for fragbed files')
        if args.max_fraglen < 0 or args.max_fraglen > 2000:
            raise ValueError('--max_fraglen of {} is out-of-range '
                             '(0-2000)'.format(args.max_fraglen))

    try:
        args.extractor = {
            'bigwig': backend.extract_bigwig_to_file,
            'fasta': backend.extract_fasta_to_file,
            'fragbed':
                lambda fragment_bed, output_dir, mode:
                backend.extract_fragment_bed_to_file(
                    fragment_bed, output_dir, args.genome_file,
                    args.max_fraglen, mode=mode)
        }[args.filetype]
    except KeyError:
        raise ValueError('Invalid file type specified.')

    return args


if __name__ == '__main__':
    args = parse_args()
    full_output_path = os.path.join(args.output_dir,
                                    os.path.basename(args.input_file))
    args.extractor(args.input_file, full_output_path, mode=args.mode)
