#!/usr/bin/env python
#
# Copyright (C) 2013-2016 DNAnexus, Inc.
#
# This file is part of dx-toolkit (DNAnexus platform client libraries).
#
#   Licensed under the Apache License, Version 2.0 (the "License"); you may not
#   use this file except in compliance with the License. You may obtain a copy
#   of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#   License for the specific language governing permissions and limitations
#   under the License.

import sys, collections
import os
import json
import argparse
from dxpy.utils.printing import *
from dxpy.utils import merge
from dxpy.system_requirements import SystemRequirementsDict
from dxpy.cli.exec_io import *
from dxpy.cli import try_call
from dxpy.cli.parsers import (exec_input_args, process_instance_type_arg, instance_type_arg, process_properties_args, property_args, tag_args, extra_args, process_extra_args)

parser = argparse.ArgumentParser(description='Creates a new job to run the named function with the specified input.  If successful, prints the ID of the new job.',
                                 parents=[exec_input_args, instance_type_arg, extra_args, property_args, tag_args])
parser.add_argument('function', help='Name of the function to run')
parser.add_argument('--name', help='Name for the new job (default is the current job name, plus ":<function>")')
parser.add_argument('--depends-on', metavar='JOB_OR_OBJECT_ID', nargs='*', help='Job and/or data object IDs that must finish or close before the new job should be run.  WARNING: For proper parsing, do not use this flag directly before the *function* parameter.')
parser.add_argument('--head-job-on-demand', help='Whether the head job should be run on an on-demand instance', action='store_true', default=None)
# --test: Specify to print the JSON mapping that would have been supplied to
# the /job/new API call, and additionally short-circuit before issuing the API
# request.
parser.add_argument("--test", action="store_true", help=argparse.SUPPRESS)
args = parser.parse_args()

entry_point_inputs = ExecutableInputs()
entry_point_inputs.update_from_args(args)

def get_job_new_input(args):
    job_new_input = {"function": args.function}

    if args.name is not None:
        job_new_input["name"] = args.name

    if args.depends_on is not None:
        job_new_input["dependsOn"] = args.depends_on

    if args.instance_type is not None:
        try_call(process_instance_type_arg, args, False)
        job_new_input["systemRequirements"] = SystemRequirementsDict.from_instance_type(args.instance_type, args.function).as_dict()
    
    if args.head_job_on_demand is not None:
        job_new_input['headJobOnDemand'] = args.head_job_on_demand

    if args.properties is not None:
        try_call(process_properties_args, args)
        job_new_input["properties"] = args.properties

    if args.tags is not None:
        job_new_input["tags"] = args.tags

    if args.extra_args is not None:
        try_call(process_extra_args, args)
        merge(job_new_input,args.extra_args)

    job_new_input["input"] = entry_point_inputs.inputs
    return job_new_input

if os.environ.get('DX_JOB_ID') is not None:
    import dxpy.api

    job_new_input = get_job_new_input(args)

    if args.test is True:
        print(json.dumps(job_new_input))
        sys.exit(0)

    resp = dxpy.api.job_new(job_new_input)

    print(resp["id"])
else:
    from dxpy.utils.local_exec_utils import queue_entry_point
    if args.test is True:
        job_new_input = get_job_new_input(args)
        print(json.dumps(job_new_input))
        sys.exit(0)

    print(queue_entry_point(function=args.function,
                            input_hash=entry_point_inputs.inputs,
                            depends_on=args.depends_on,
                            name=args.name))
