#!/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)

        fc_str = eng_notation.num_to_str(fc)
        print("Extracting channels %s, given center frequency at %sHz (ARFCN %d)" % (str(ca), fc_str, center_arfcn))

        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
            freq_diff_str = "+" if 0 <= freq_diff else ""
            freq_diff_str += eng_notation.num_to_str(freq_diff)
            print("ARFCN %d is at %sHz %sHz" % (channel, fc_str, freq_diff_str))

            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!")
