import sys
import pandas
import pm4py

from pm4py.algo.discovery.inductive import algorithm as inductive_miner
from pm4py.algo.discovery.heuristics.variants import plusplus as heuristics_miner
from pm4py.algo.discovery.dfg import algorithm as dfg_discovery

from pm4py.visualization.heuristics_net import visualizer as hn_visualizer
from pm4py.visualization.process_tree import visualizer as pt_visualizer
from pm4py.visualization.dfg import visualizer as dfg_visualization
from pm4py.visualization.bpmn import visualizer as bpmn_visualization

from pm4py.algo.filtering.log.attributes import attributes_filter
from pm4py.objects.conversion.process_tree import converter


CASE = ""
ACTIVITY = ""
TIMESTAMP = ""

OUTPUT_FILE = ""


def generate_process_tree(event_log):
    parameters = {inductive_miner.Variants.IM_CLEAN.value.Parameters.NOISE_THRESHOLD: 0.5}

    tree = inductive_miner.apply_tree(event_log, variant = inductive_miner.Variants.IM_CLEAN)

    gviz = pt_visualizer.apply(tree)
    
    pt_visualizer.view(gviz)

    pt_visualizer.save(gviz, OUTPUT_FILE + "-inductive" + ".png")

    return gviz


def generate_heuristic_net(event_log):
    heu_net = heuristics_miner.apply_heu(event_log, parameters={
        heuristics_miner.Parameters.DEPENDENCY_THRESH: -1,
        heuristics_miner.Parameters.AND_MEASURE_THRESH: 0.65,
        heuristics_miner.Parameters.MIN_ACT_COUNT: 0,
        heuristics_miner.Parameters.MIN_DFG_OCCURRENCES: 0
        })
    
    gviz = hn_visualizer.apply(heu_net)

    hn_visualizer.view(gviz)

    hn_visualizer.save(gviz, OUTPUT_FILE + "-heuristic" + ".jpg")

    return gviz


def generate_dfg(event_log):
    parameters = {dfg_visualization.Variants.PERFORMANCE.value.Parameters.FORMAT: "svg"}

    dfg = dfg_discovery.apply(event_log, variant = dfg_discovery.Variants.PERFORMANCE)
    
    gviz = dfg_visualization.apply(dfg, log = event_log, variant = dfg_visualization.Variants.PERFORMANCE, parameters = parameters)
    
    dfg_visualization.view(gviz)
    
    dfg_visualization.save(gviz, OUTPUT_FILE + "-dfg" + ".svg")

    return gviz


def generate_bpmn(event_log):    
    tree = inductive_miner.apply_tree(event_log, variant = inductive_miner.Variants.IM_CLEAN)
    
    bpmn = converter.apply(tree, variant = converter.Variants.TO_BPMN)

    gviz =  bpmn_visualization.apply(bpmn)

    bpmn_visualization.view(gviz)

    bpmn_visualization.save(gviz, OUTPUT_FILE + "-bpmn" + ".jpg")    
    
    
def import_csv(file_path):
    csv = pandas.read_csv(file_path, sep = ',', error_bad_lines = False, index_col = False)
    
    return csv


def get_event_log(csv):
    event_log = pm4py.format_dataframe(csv, case_id = CASE, activity_key = ACTIVITY, timestamp_key = TIMESTAMP)
    
    start_activities = pm4py.get_start_activities(event_log)
    
    end_activities = pm4py.get_end_activities(event_log)
    
    print("Start activities: {}\nEnd activities: {}".format(start_activities, end_activities))
    
    return event_log


def generate(event_log):
    generate_dfg(event_log)

    generate_heuristic_net(event_log)

    generate_process_tree(event_log)

    generate_bpmn(event_log)


def main():
    input_file = sys.argv[1]

    global CASE, ACTIVITY, TIMESTAMP, OUTPUT_FILE
    OUTPUT_FILE =  sys.argv[2]
    
    CASE =  sys.argv[3]
    ACTIVITY =  sys.argv[4]
    TIMESTAMP =  sys.argv[5]

    csv = import_csv(input_file)
    event_log = get_event_log(csv)

    generate(event_log)


if __name__ == "__main__":
    main()
