import argparse, sys

from py_cmdtabs.cmdtabs import CmdTabs
from py_exp_calc.main_modules import *

def based_0(string): return int(string) - 1
def list_based_0(string): return CmdTabs.parse_column_indices(",", string)
def double_split(string, sep1=";", sep2=","):
    return [sublst.split(sep2) for sublst in string.strip().split(sep1)]

## Common options
def add_common_options(parser):
    parser.add_argument("-i", "--input_file", dest="input",
        help="Path to input file")
    parser.add_argument("-o", "--output_file", dest="output",
        help="Path to input file")

def clusterize(args = None):
    if args == None: args = sys.argv[1:]
    parser = argparse.ArgumentParser(description="Get clusters")
    add_common_options(parser)
    parser.add_argument("-x", "--x_dim", dest="x_dim",
        help="Item list file for x axis")
    parser.add_argument("-y", "--y_dim", dest="y_dim",
        help="Item list file for y axis")
    parser.add_argument("-n", "--n_clusters", dest="n_clusters", type=int,
        help="N clusters for cut tree algorithm")
    parser.add_argument("-H", "--height", dest="height",
        help="Cut the tree with cut tree algorithm at specifc height")
    parser.add_argument("-c", "--clustering", dest="clustering", default='cut_tree',
        help="Method to identify clusters in hierarchical tree")        
    parser.add_argument("-r","--report", dest="report", default= False, action="store_true",
        help="Make report. Default false")

    opts =  vars(parser.parse_args(args))
    main_clusterize(opts)


def inference_analyzer(args = None):
    if args == None: args = sys.argv[1:]
    parser = argparse.ArgumentParser(description="Perform statistics form table")
    add_common_options(parser)
    parser.add_argument("-f", "--factor_indexes", dest="factor_indexes", type= list_based_0,
        help="Specify col number for factors")
    parser.add_argument("--alt_hyp", dest="alt_hyp", default= "two-sided",
        help="Select alternative hypotesis with optinos: two-sided, less, greater")
    parser.add_argument("-np","--no_parametric", dest="no_parametric", default= False, action='store_true', 
        help="Use this option if you want to specify not parametric analysis for all tests")
    parser.add_argument("--adj_pval", dest="adj_pval", default= None,
        help="Select multiple testing adjustment: bonferroni, sidak, holm-sidak, holm, simes-hochberg, hommel, fdr_bh, fdr_by, fdr_tsbh, fdr_tsbky")
    parser.add_argument("--header", dest = "header", default=False, action='store_true',
                        help="This is to check if you got a header")
    opts =  vars(parser.parse_args(args))
    main_inference_analyzer(opts)

def stable_select(args=None):
    if args is None:
        args = sys.argv[1:]
    parser = argparse.ArgumentParser(
        description="Stable feature selection (e.g., elastic_net) from data table + label file"
    )
    add_common_options(parser)
    parser.add_argument("--label", dest="label", required=True,
        help="Path to label file (single column, no header)")
    parser.add_argument("--sep", dest="sep", default="\t",
        help="Separator for input data table. Default: TAB")
    parser.add_argument("--header", dest="header", type=int, default=0,
        help="Header row index for data table. Default: 0")
    parser.add_argument("--index_col", dest="index_col", type=int, default=0,
        help="Index column for data table. Default: 0")
    parser.add_argument("--regularization_strength", dest="regularization_strength", type=float, default=0.5,
        help="Regularization strength parameter. Default: 0.25. lowest value is 0, which implies no regularization.")
    parser.add_argument("--l1_ratio", dest="l1_ratio", type=float, default=0.01,
        help="Elastic Net mixing parameter (0=L2, 1=L1). Default: 0.05.")
    parser.add_argument("--number_iter", dest="number_iter", type=int, default=50,
        help="Number of iterations. Default: 10")
    parser.add_argument("--sample_fraction", dest="sample_fraction", type=float, default=0.8,
        help="Sample fraction per iteration. Default: 0.8")
    parser.add_argument("--proportion_threshold", dest="proportion_threshold", type=float, default=0.5,
        help="Stability proportion threshold. Default: 0.5")
    parser.add_argument("--random_state", dest="random_state", type=int, default=0,
        help="Random state. Default: 0")
    parser.add_argument("--return_stability", dest="return_stability",
        default=False, action="store_true",
        help="If set, return stability metrics (depends on stable_selection implementation). Default: False")

    opts = vars(parser.parse_args(args))
    main_stable_select(opts)


def performancer(args = None):
    if args == None: args = sys.argv[1:]
    parser = argparse.ArgumentParser(description="Get clusters")
    add_common_options(parser)
    parser.add_argument("-c","--control_file", dest="control_file", default=None,
        help="Control file name")
    parser.add_argument("--metrics", dest="metrics", default=["tpr", "fnr", "tnr", "fpr", "coverage", "prec", "f1", "mcc"], 
                        type = lambda x: x.strip().split(","),
                        help= """Add the different metrics necesssary to 
                        evaluate the system: acc, f1, prec, tpr, fnr, tnr, fpr, bal_acc, mcc""")
    parser.add_argument("--generate_report", dest= "generate_report", default= False, action="store_true")
    parser.add_argument("--generate_table", dest = "generate_table", default = False, action="store_true")
    parser.add_argument("--ascending_order", dest= "ascending", default=False, action="store_true" )
    opts =  vars(parser.parse_args(args))
    main_performancer(opts)