#!/usr/bin/env python3

import argparse
import sys
from covernantlib import bedtowiggle
from covernantlib import extract
from covernantlib import plotmatrix
from covernantlib import ratio
from covernantlib import rescalewig


__author__ = "Konrad Foerstner <konrad@foerstner.org>"
__copyright__ = "2013-2017 by Konrad Foerstner <konrad@foerstner.org>"
__license__ = "ISC license"
__email__ = "konrad@foerstner.org"
__version__ = "0.3.0"


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--version", "-v", default=False, action="store_true",
        help="show version")
    subparsers = parser.add_subparsers(help="commands")

    ratio_plot_parser = subparsers.add_parser(
        "ratio", help="Generate ratio plots of two alignment files in Bam formar.")
    ratio_plot_parser.set_defaults(func=plot_ratios)
    ratio_plot_parser.add_argument(
        "--denominator",  dest="denominator_bam_file")
    ratio_plot_parser.add_argument(
        "--numerator", dest="numerator_bam_file")
    ratio_plot_parser.add_argument(
        "--output_prefix", "-o", default="", required=False)
    ratio_plot_parser.add_argument(
        "--paired_end", default=False, action="store_true",
        help="Paired reads are treated as one fragment an the start and "
        "end positions are used accordingly")
    ratio_plot_parser.add_argument(
        "--window_size", type=int, default=1,
        help="Window size for sliding window average calculation. "
        "Must be an odd number. (Default is 1).")
    ratio_plot_parser.add_argument(
        "--step_size", type=int, default=1,
        help="Step size for sliding window average calculation."
        " Default is 1.")
    ratio_plot_parser.add_argument(
        "--factor_numerator", type=float, default=None,
        help="A factor the numerator values are are multiplied with.")
    ratio_plot_parser.add_argument(
        "--factor_denominator", type=float, default=None,
        help="A factor the denominator values are are multiplied with.")
    ratio_plot_parser.add_argument(
        "--keep_zero_coverage", default=False, action="store_true",
        help="Also write coordinates that have a coverage of 0. "
        "Default is to discard those.")
    ratio_plot_parser.add_argument("--denominator_name", default=None)
    ratio_plot_parser.add_argument("--numerator_name", default=None)
    ratio_plot_parser.add_argument("--ratio_name", default=None)

    extract_parser = subparsers.add_parser(
        "extract", help="Extract coverage values from a wiggle file based "
        "on coordinates in a bed file and generate a matrix.")
    extract_parser.set_defaults(func=extract_coverages)
    extract_parser.add_argument("coverage_file")
    extract_parser.add_argument("coordinate_file")
    extract_parser.add_argument("--output_prefix", default="output")
    extract_parser.add_argument(
        "--flip_reverse_strand", default=False,
        action="store_true",
        help="Flip the coverage value list of entries located at the minus "
        "strand")
    extract_parser.add_argument(
        "--matrix_alignment", choices=["left", "center", "right"], default="left",
        help="default is 'left'.")
    extract_parser.add_argument(
        "--window_size", type=int, default=None,
        help="Window size for sliding window average calculation. "
        "Must be an odd number.")
    extract_parser.add_argument(
        "--step_size", type=int, default=1,
        help="Step size for sliding window average calculation."
        " Default is 1.")

    plot_matrix_parser = subparsers.add_parser(
        "plot_matrix", help="Plot the content of the extracted coverage "
        "matrix.")
    plot_matrix_parser.set_defaults(func=plot_matrix)
    plot_matrix_parser.add_argument("matrix_file")
    plot_matrix_parser.add_argument(
        "--output_file", default="matrix_plots.pdf")
    plot_matrix_parser.add_argument(
        "--share_x_range", default=False, action="store_true",
        help="Use the same x range in all plots.")
    plot_matrix_parser.add_argument(
        "--share_y_max", default=False, action="store_true",
            help="Use the same maximum y value in all plots.")

    bed_to_wiggle_parser = subparsers.add_parser(
        "bed_to_wig", help="Converts Bed files to coverage files in wiggle formats")
    bed_to_wiggle_parser.set_defaults(func=bed_to_wig)
    bed_to_wiggle_parser.add_argument("input_file", help="Input Bed file")
    bed_to_wiggle_parser.add_argument("--output_prefix", default="output")
    bed_to_wiggle_parser.add_argument("--window_size", default="1", type=int)
    bed_to_wiggle_parser.add_argument("--step_size", default="1", type=int)


    rescale_wiggle_parser = subparsers.add_parser(
        "rescale_wig", help="Multiplies each value of a wiggle file with a"
        " given factor.")
    rescale_wiggle_parser.set_defaults(func=rescale_wiggle)
    rescale_wiggle_parser.add_argument("input_file", help="Input wiggle file")
    rescale_wiggle_parser.add_argument("factor", type=float, default=1.0)
    rescale_wiggle_parser.add_argument("--output_prefix", default="output")
    
    args = parser.parse_args()
    if args.version is True:
        print("COVERnant version " + __version__)
    elif "func" in dir(args):
        args.func(args)
    else:
        parser.print_help()

def plot_ratios(args):
    ratio.calc_ratio(args)

def extract_coverages(args):
    extract.extract(args)

def plot_matrix(args):
    plotmatrix.plot_matrix(args)

def bed_to_wig(args):
    bedtowiggle.bed_to_wiggle(
        args.input_file, args.output_prefix, args.window_size, args.step_size)

def rescale_wiggle(args):
    rescalewig.rescale_wiggle(args)
    
main()
