#!/usr/bin/python
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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 ast
import codegen
import os
import sys
import zipimport
sys.path.append(os.getcwd())
from runtime import AmaContext, Environment

# os.chdir(os.getcwd() + '/build/resources/test/')
# import zipfile
# zip = zipfile.ZipFile('pyspark.zip')
# zip.extractall()
# zip = zipfile.ZipFile('py4j-0.10.4-src.zip', 'r')
# zip.extractall()
# sys.path.insert(1, os.getcwd() + '/executor/src/test/resources/pyspark')
# sys.path.insert(1, os.getcwd() + '/executor/src/test/resources/py4j')

# py4j_path = 'spark-2.2.1-bin-hadoop2.7/python/lib/py4j-0.10.4-src.zip'
# py4j_importer = zipimport.zipimporter(py4j_path)
# py4j = py4j_importer.load_module('py4j')
from py4j.java_gateway import JavaGateway, GatewayClient, java_import
from py4j.protocol import Py4JJavaError
from pyspark.conf import SparkConf
from pyspark.context import SparkContext
from pyspark.rdd import RDD
from pyspark.files import SparkFiles
from pyspark.storagelevel import StorageLevel
from pyspark import accumulators
from pyspark.accumulators import Accumulator, AccumulatorParam
from pyspark.broadcast import Broadcast
from pyspark.serializers import MarshalSerializer, PickleSerializer
from pyspark.sql import SparkSession
from pyspark.sql import Row

client = GatewayClient(port=int(sys.argv[1]))
gateway = JavaGateway(client, auto_convert=True)
entry_point = gateway.entry_point
queue = entry_point.getExecutionQueue()

java_import(gateway.jvm, "org.apache.spark.SparkEnv")
java_import(gateway.jvm, "org.apache.spark.SparkConf")
java_import(gateway.jvm, "org.apache.spark.api.java.*")
java_import(gateway.jvm, "org.apache.spark.api.python.*")
java_import(gateway.jvm, "org.apache.spark.mllib.api.python.*")
java_import(gateway.jvm, "org.apache.spark.sql.*")
java_import(gateway.jvm, "org.apache.spark.sql.hive.*")
java_import(gateway.jvm, "scala.Tuple2")

jconf = entry_point.getSparkConf()
jsc = entry_point.getJavaSparkContext()

job_id = entry_point.getJobId()
javaEnv = entry_point.getEnv()

env = Environment(javaEnv.name(), javaEnv.master(), javaEnv.inputRootPath(), javaEnv.outputRootPath(), javaEnv.workingDir(), javaEnv.configuration())
conf = SparkConf(_jvm=gateway.jvm, _jconf=jconf)
conf.setExecutorEnv('PYTHONPATH', ':'.join(sys.path))
sc = SparkContext(jsc=jsc, gateway=gateway, conf=conf)
spark = SparkSession(sc, entry_point.getSparkSession())

ama_context = AmaContext(sc, spark, job_id, env)

while True:
    actionData = queue.getNext()
    resultQueue = entry_point.getResultQueue(actionData._2())
    actionSource = actionData._1()
    tree = ast.parse(actionSource)
    exports = actionData._3()

    for node in tree.body:

        wrapper = ast.Module(body=[node])
        try:
            co = compile(wrapper, "<ast>", 'exec')
            exec (co)
            resultQueue.put('success', actionData._2(), codegen.to_source(node), '')

            #if this node is an assignment, we need to check if it needs to be persisted
            try:
                persistCode = ''
                if(isinstance(node,ast.Assign)):
                    varName = node.targets[0].id
                    if(exports.containsKey(varName)):
                        persistCode = varName + ".write.save(\"" + env.working_dir + "/" + job_id + "/" + actionData._2() + "/" + varName + "\", format=\"" + exports[varName] + "\", mode='overwrite')"
                        persist = compile(persistCode, '<stdin>', 'exec')
                        exec(persist)

            except:
                resultQueue.put('error', actionData._2(), persistCode, str(sys.exc_info()[1]))
        except:
            resultQueue.put('error', actionData._2(), codegen.to_source(node), str(sys.exc_info()[1]))
    resultQueue.put('completion', '', '', '')