#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# @file
# @author Pieter Robyns <pieter.robyns@uhasselt.be>
# @section LICENSE
#
# Gr-gsm is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# Gr-gsm 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with gr-gsm; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
#

##################################################
# gr-gsm channelizer
#
# Standalone application to channelize a wideband
# GSM capture file into multiple seperate capture
# files for the specified ARFCNs.
##################################################

from gnuradio import blocks
from gnuradio import eng_notation
from gnuradio import filter
from gnuradio import gr
from gnuradio.eng_option import eng_option
from gnuradio.filter import firdes
from argparse import ArgumentParser, ArgumentTypeError, RawDescriptionHelpFormatter
import grgsm.arfcn as arfcn
from gnuradio.filter import pfb
import math
import os

EXTRA_HELP = """
Example usage:
grgsm_channelize.py -f my_wideband_capture.cfile -c 925.2e6 990 991 992 993 994 995 1019 1020 1021 1022 1023

The above example will channelize my_wideband_capture.cfile, in this case a cfile captured at
925.2 MHz centered (ARFCN 975) and 20 Msps. As a result, 12 files will be generated for
ARFCNs 975 - 1023 at 1 Msps each.
"""

def eng_float(value):
    try:
        return eng_notation.str_to_num(value)
    except:
        raise ArgumentTypeError("invalid engineering notation value: {0}".format(value))

def gsm_band(value):
    choices = arfcn.get_bands()
    if value in choices:
        return value
    else:
        raise ArgumentTypeError("invalid GSM band: {0}. Possible choices are: {1}".format(value, choices))

class grgsm_channelize(gr.top_block):
    def __init__(self, channels, resamp_rate, fc, band, samp_rate, input_file, dest_dir, data_type="complex"):
        gr.top_block.__init__(self, "grgsm_channelize")

        ##################################################
        # Parameters
        ##################################################
        self.channels = channels
        self.resamp_rate = resamp_rate
        self.fc = fc
        self.band = band
        self.samp_rate = samp_rate
        self.blocks_resamplers = {}
        self.blocks_rotators = {}
        self.blocks_file_sinks = {}
        
        ##################################################
        # Blocks and connections
        ##################################################
        self.source = None
        if data_type == "ishort":
            self.blocks_file_source = blocks.file_source(gr.sizeof_short, input_file, False)
            self.source = blocks.interleaved_short_to_complex(False, False)
            self.connect((self.blocks_file_source, 0), (self.source, 0))
        elif data_type == "complex":
            self.source = blocks.file_source(gr.sizeof_gr_complex, input_file, False)

        print("Extracting channels %s, given that the center frequency is at %s" % (str(channels), eng_notation.num_to_str(fc)))

        for channel in channels:
            channel_freq = arfcn.arfcn2downlink(channel, band)
            if channel_freq is None:
                print("Warning: invalid ARFCN %d for band %s" % (channel, band))
                continue
            freq_diff = channel_freq - fc
            print("ARFCN %d is at fc %+d KHz" % (channel, int(freq_diff / 1000.0)))

            self.blocks_resamplers[channel] = pfb.arb_resampler_ccf( resamp_rate, taps=None, flt_size=32)
            self.blocks_rotators[channel] = blocks.rotator_cc(-2*math.pi*(freq_diff)/samp_rate)
            self.connect( (self.source, 0), (self.blocks_rotators[channel], 0) )
            self.connect( (self.blocks_rotators[channel], 0), (self.blocks_resamplers[channel], 0) )

            self.blocks_file_sinks[channel] = blocks.file_sink(gr.sizeof_gr_complex, dest_dir+"/out_" + str(channel) + ".cfile", False)
            self.blocks_file_sinks[channel].set_unbuffered(False)
            self.connect((self.blocks_resamplers[channel], 0), (self.blocks_file_sinks[channel], 0))


if __name__ == '__main__':
    parser = ArgumentParser(formatter_class=RawDescriptionHelpFormatter, description='Split wideband a GSM capture into seperate files per ARFCN.', add_help=True, epilog=EXTRA_HELP)
    parser.add_argument(dest="channel", type=int, nargs='+',
        help="List of ARFCNs")
    parser.add_argument("-s", "--samp-rate", dest="samp_rate", type=eng_float, default=eng_notation.num_to_str(2e7),
        help="Sample rate of the wideband capture file [default=%(default)s]")
    parser.add_argument("-f", "--fc", dest="fc", type=eng_float, default=eng_notation.num_to_str(935e6), required=True,
        help="Carrier frequency in Hz [default=%(default)s]")
    parser.add_argument("-b", "--band", dest="band", type=gsm_band, default='E-GSM',
        help="GSM band [default=%(default)s]") #TODO: add automatic discovery based on fc
    parser.add_argument("-o", "--out-samp-rate", dest="out_samp_rate", type=eng_float, default=eng_notation.num_to_str(1e6),
        help="Sample rate of the output capture files [default=%(default)s]")
    parser.add_argument("-i", "--input_file", dest="input_file", type=str, required=True,
        help="Path to wideband GSM capture file")
    parser.add_argument("-t", "--data_type", dest="data_type", type=str, choices=["complex","ishort"], default="complex",
        help="Type of the input file [default=%(default)s]")
    parser.add_argument("-d", "--dest_dir", dest="dest_dir", type=str, 
        help="Destination directory - if not given defaults to input file name without extension")
        
    args = parser.parse_args()
    
    if not os.path.exists(args.input_file):
        raise IOError(args.input_file + " does not exist")

    input_filename, _ = os.path.splitext(os.path.basename(args.input_file))

    if args.dest_dir is None:
        args.dest_dir = input_filename
    
    if not os.path.exists("./"+args.dest_dir):
        os.makedirs("./"+args.dest_dir)


    if args.samp_rate % args.out_samp_rate != 0:
        raise Exception("Input sample rate should be multiple of output sample rate in order to get integer decimation.")

    resamp_rate = args.out_samp_rate / args.samp_rate
    print("Input sample rate: " + eng_notation.num_to_str(args.samp_rate))
    print("Output sample rate: " + eng_notation.num_to_str(args.out_samp_rate))
    print("==> using resample rate of " + str(resamp_rate))

    tb = grgsm_channelize(channels=args.channel,
         resamp_rate=resamp_rate,
         fc=args.fc,
         band=args.band,
         samp_rate=args.samp_rate,
         input_file=args.input_file,
         dest_dir=args.dest_dir,         
         data_type=args.data_type
         )
    tb.start()
    tb.wait()
    print("Done!")
