"""Python proxy to run Swift action.

/*
 * 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 os
import glob
import sys
import subprocess
import codecs
import json
sys.path.append('../actionProxy')
from actionproxy import ActionRunner, main, setRunner  # noqa

SRC_EPILOGUE_FILE = '/swift3Action/epilogue.swift'
DEST_SCRIPT_FILE = '/swift3Action/spm-build/main.swift'
DEST_SCRIPT_DIR = '/swift3Action/spm-build'
DEST_BIN_FILE = '/swift3Action/spm-build/.build/release/Action'

BUILD_PROCESS = ['./swiftbuildandlink.sh']


class Swift3Runner(ActionRunner):

    def __init__(self):
        ActionRunner.__init__(self, DEST_SCRIPT_FILE, DEST_BIN_FILE)

    # remove pre-existing binary before receiving a new binary
    def preinit(self):
        try:
            os.remove(self.binary)
        except: pass

    def epilogue(self, init_message):
        # skip if executable already exists (was unzipped)
        if os.path.isfile(self.binary):
            return

        if 'main' in init_message:
            main_function = init_message['main']
        else:
            main_function = 'main'
        # make sure there is a main.swift file
        open(DEST_SCRIPT_FILE, 'a').close()

        with codecs.open(DEST_SCRIPT_FILE, 'a', 'utf-8') as fp:
            os.chdir(DEST_SCRIPT_DIR)
            for file in glob.glob("*.swift"):
                if file not in ["Package.swift", "main.swift", "_WhiskJSONUtils.swift", "_Whisk.swift"]:
                    with codecs.open(file, 'r', 'utf-8') as f:
                        fp.write(f.read())
            with codecs.open(SRC_EPILOGUE_FILE, 'r', 'utf-8') as ep:
                fp.write(ep.read())

            fp.write('_run_main(mainFunction: %s)\n' % main_function)

    def build(self, init_message):
        # short circuit the build, if there already exists a binary
        # from the zip file
        if os.path.isfile(self.binary):
            # file may not have executable permission, set it
            os.chmod(self.binary, 0o555)
            return

        p = subprocess.Popen(
            BUILD_PROCESS,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            cwd=DEST_SCRIPT_DIR)

        # run the process and wait until it completes.
        # stdout/stderr will not be None because we passed PIPEs to Popen
        (o, e) = p.communicate()

        # stdout/stderr may be either text or bytes, depending on Python
        # version, so if bytes, decode to text. Note that in Python 2
        # a string will match both types; so also skip decoding in that case
        if isinstance(o, bytes) and not isinstance(o, str):
            o = o.decode('utf-8')
        if isinstance(e, bytes) and not isinstance(e, str):
            e = e.decode('utf-8')

        if o:
            sys.stdout.write(o)
            sys.stdout.flush()

        if e:
            sys.stderr.write(e)
            sys.stderr.flush()

    def env(self, message):
        env = ActionRunner.env(self, message)
        args = message.get('value', {}) if message else {}
        env['WHISK_INPUT'] = json.dumps(args)
        return env


if __name__ == '__main__':
    setRunner(Swift3Runner())
    main()

[((26, 0, 26, 33), 'sys.path.append', 'sys.path.append', ({(26, 16, 26, 32): '"""../actionProxy"""'}, {}), "('../actionProxy')", False, 'import sys\n'), ((114, 4, 114, 10), 'actionproxy.main', 'main', ({}, {}), '()', False, 'from actionproxy import ActionRunner, main, setRunner\n'), ((40, 8, 40, 68), 'actionproxy.ActionRunner.__init__', 'ActionRunner.__init__', ({(40, 30, 40, 34): 'self', (40, 36, 40, 52): 'DEST_SCRIPT_FILE', (40, 54, 40, 67): 'DEST_BIN_FILE'}, {}), '(self, DEST_SCRIPT_FILE, DEST_BIN_FILE)', False, 'from actionproxy import ActionRunner, main, setRunner\n'), ((50, 11, 50, 38), 'os.path.isfile', 'os.path.isfile', ({(50, 26, 50, 37): 'self.binary'}, {}), '(self.binary)', False, 'import os\n'), ((74, 11, 74, 38), 'os.path.isfile', 'os.path.isfile', ({(74, 26, 74, 37): 'self.binary'}, {}), '(self.binary)', False, 'import os\n'), ((79, 12, 83, 32), 'subprocess.Popen', 'subprocess.Popen', (), '', False, 'import subprocess\n'), ((106, 14, 106, 45), 'actionproxy.ActionRunner.env', 'ActionRunner.env', ({(106, 31, 106, 35): 'self', (106, 37, 106, 44): 'message'}, {}), '(self, message)', False, 'from actionproxy import ActionRunner, main, setRunner\n'), ((108, 29, 108, 45), 'json.dumps', 'json.dumps', ({(108, 40, 108, 44): 'args'}, {}), '(args)', False, 'import json\n'), ((45, 12, 45, 34), 'os.remove', 'os.remove', ({(45, 22, 45, 33): 'self.binary'}, {}), '(self.binary)', False, 'import os\n'), ((60, 13, 60, 56), 'codecs.open', 'codecs.open', ({(60, 25, 60, 41): 'DEST_SCRIPT_FILE', (60, 43, 60, 46): '"""a"""', (60, 48, 60, 55): '"""utf-8"""'}, {}), "(DEST_SCRIPT_FILE, 'a', 'utf-8')", False, 'import codecs\n'), ((61, 12, 61, 37), 'os.chdir', 'os.chdir', ({(61, 21, 61, 36): 'DEST_SCRIPT_DIR'}, {}), '(DEST_SCRIPT_DIR)', False, 'import os\n'), ((62, 24, 62, 44), 'glob.glob', 'glob.glob', ({(62, 34, 62, 43): '"""*.swift"""'}, {}), "('*.swift')", False, 'import glob\n'), ((76, 12, 76, 40), 'os.chmod', 'os.chmod', ({(76, 21, 76, 32): 'self.binary', (76, 34, 76, 39): '(365)'}, {}), '(self.binary, 365)', False, 'import os\n'), ((98, 12, 98, 31), 'sys.stdout.write', 'sys.stdout.write', ({(98, 29, 98, 30): 'o'}, {}), '(o)', False, 'import sys\n'), ((99, 12, 99, 30), 'sys.stdout.flush', 'sys.stdout.flush', ({}, {}), '()', False, 'import sys\n'), ((102, 12, 102, 31), 'sys.stderr.write', 'sys.stderr.write', ({(102, 29, 102, 30): 'e'}, {}), '(e)', False, 'import sys\n'), ((103, 12, 103, 30), 'sys.stderr.flush', 'sys.stderr.flush', ({}, {}), '()', False, 'import sys\n'), ((66, 17, 66, 61), 'codecs.open', 'codecs.open', ({(66, 29, 66, 46): 'SRC_EPILOGUE_FILE', (66, 48, 66, 51): '"""r"""', (66, 53, 66, 60): '"""utf-8"""'}, {}), "(SRC_EPILOGUE_FILE, 'r', 'utf-8')", False, 'import codecs\n'), ((64, 25, 64, 56), 'codecs.open', 'codecs.open', ({(64, 37, 64, 41): 'file', (64, 43, 64, 46): '"""r"""', (64, 48, 64, 55): '"""utf-8"""'}, {}), "(file, 'r', 'utf-8')", False, 'import codecs\n')]