#!/usr/bin/env python

"""
Script that makes it easier to start IGV from the command line, optionally with initial data files and/or at a
specific locus.
"""

import configargparse
import os
import re
import sys

import igv_api

parser = configargparse.ArgParser(description="Script for starting IGV, optionally with initial data files and/or at a specific locus.",
                                  default_config_files=["~/.igv_plotter"],
                                  formatter_class=configargparse.DefaultsFormatter)

parser.add("files_or_locus", metavar="files and/or locus", nargs="*", help="Optionally, one or more files to load into "
    "IGV at startup and/or a locus to jump to (for example chr1:12345). For a list of accepted IGV file formats,"
    " see https://www.broadinstitute.org/igv/RecommendedFileFormats")
parser.add("--igv-jar-path", help="Path to igv.jar", default=os.path.join(os.path.dirname(os.path.abspath(__file__)), "igv.jar"))
parser.add("--width", type=int, help="IGV window width.", default=800)
parser.add("--height", type=int, help="IGV window height.", default=600)
parser.add("-c", "--config-file", help="Config file path", is_config_file=True)
parser.add("-m", "--max-memory", help="IGV max memory limit (eg. 2G)", default="1024M")
parser.add("-g", "--genome", help="Either the local path of a .genome file, or a genome id (eg. hg19) chosen from "
    "the right-most column of http://igv.broadinstitute.org/genomes/genomes.txt")
parser.add("-p", "--preference", action="append", metavar="KEY=VALUE", help="Changes one of the IGV settings "
    "(eg. -p DEFAULT_FONT_SIZE=10). For a full list of keys & example values that can be set, see: "
    "https://github.com/broadinstitute/IGV/blob/master/src/org/broad/igv/PreferenceManager.java#L928")
parser.add("--view-as-pairs", action="store_true", help="In .bam tracks, view reads as pairs")
parser.add("--expand", dest="compactness_command", action="store_const", const="expand", help="Expand all tracks")
parser.add("--squish", dest="compactness_command", action="store_const", const="squish", help="Squish all tracks")
parser.add("--collapse", dest="compactness_command", action="store_const", const="collapse", help="Collapse all tracks")
args = parser.parse()

# validate arg values
def is_valid_locus_or_region(locus_or_region):
    return igv_robot._match_locus_string(locus_or_region) or igv_robot._match_region_string(locus_or_region)

# create igv_robot
args.igv_jar_path = os.path.abspath(os.path.expanduser(args.igv_jar_path))
if not os.path.isfile(args.igv_jar_path) or not args.igv_jar_path.endswith(".jar"):
    parser.error("Invalid IGV jar path: " + args.igv_jar_path)

igv_robot = igv_api.IGVCommandLineRobot(args.igv_jar_path,
    igv_window_width=args.width,
    igv_window_height=args.height,
    max_memory=args.max_memory,
    hide_igv_window=False,
    verbose=True)


# global settings
if args.genome:
    igv_robot.genome(args.genome)
if args.view_as_pairs:
    igv_robot.view_all_tracks_as_pairs()
if args.compactness_command is not None:
    igv_robot.command(args.compactness_command)
if args.preference:
    for p in args.preference:
        key_value = p.split("=")
        if len(key_value) != 2:
            parser.error("Invalid preference arg: %(p)s. It should be of the form -p key=value" % locals())
        igv_robot.preference(key_value[0], key_value[1])


# files, loci, regions
for f in args.files_or_locus:
    if os.path.isfile(f) or f.startswith('http:'):
        igv_robot.load(f)
    elif is_valid_locus_or_region(f):
        igv_robot.goto(locus=f)
    else:
        parser.error("File doesn't exist: " + f)

try:
    igv_robot.execute()
except igv_api.IGVException as e:
    sys.exit("IGV crashed: %s" % e)
