#!/usr/bin/env python
import os

import argh
import multiprocessing
from quantdsl import QuantDslError



@argh.arg('--pool-size', help='workers in multiprocessing pool', default=multiprocessing.cpu_count(), type=int)
@argh.arg('--path-count', help='paths in Monte Carlo simulation', type=int)
@argh.arg('-c', '--calibration-url', help='URL of market calibration data')
@argh.arg('source-url', help='URL of DSL source')
def main(source_url, calibration_url=None, path_count=50000, pool_size=None):
    """
    Evaluates DSL module at source_url, given market calibration at calibration_url.
    """
    import quantdsl
    import datetime

    def getResource(url):
        if url.startswith('file://'):
            return open(url[7:]).read()
        elif url.startswith('http://'):
            import requests
            return requests.get(url)
        elif os.path.exists(url) and os.path.isfile(url):
            return open(url).read()
        else:
            raise QuantDslError("Can't open resource: %s" % url)

    dslSource = getResource(source_url)
    marketCalibrationJson = getResource(calibration_url)
    import json
    try:
        marketCalibration = json.loads(marketCalibrationJson)
    except Exception, e:
        msg = "Unable to load JSON from %s: %s: %s" % (calibration_url, e, marketCalibrationJson)
        raise ValueError(msg)

    observationTime = datetime.datetime.now().replace(tzinfo=quantdsl.utc)

    try:
        result = quantdsl.eval(dslSource,
            filename=source_url,
            isParallel=True,
            marketCalibration=marketCalibration,
            interestRate=2.5,
            pathCount=path_count,
            observationTime=observationTime,
            isMultiprocessing=True,
            poolSize=pool_size,
            isVerbose=True,
        )
    except quantdsl.QuantDslError, e:
        print "Failed to eval DSL source:"
        print dslSource
        print
        print "Error:", e
        print
    else:
        print "Result:"
        print "    mean: %.4f" % result['mean']
        print "    stderr: %.4f" % result['stderr']
        print

if __name__ == '__main__':
    argh.dispatch_command(main)