#!/usr/bin/env python

# Copyright 2017 the original author or authors.
#
# 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

from google.protobuf.compiler import plugin_pb2 as plugin
from google.protobuf.descriptor_pb2 import ServiceDescriptorProto, \
    MethodOptions
from jinja2 import Template
from simplejson import dumps

from chameleon.protos import annotations_pb2, http_pb2

template = Template("""
# Generated file; please do not edit

from simplejson import dumps, load
from structlog import get_logger
from google.protobuf.json_format import MessageToDict, ParseDict
from twisted.internet.defer import inlineCallbacks, returnValue

{% set package = file_name.replace('.proto', '') %}

{% for pypackage, module in includes %}
{% if pypackage %}
from {{ pypackage }} import {{ module }}
try:
    from {{ pypackage }} import {{ module }}_grpc
except ImportError:
    pass
{% else %}
import {{ module }}
try:
    import {{ module }}_grpc
except ImportError:
    pass
{% endif %}
{% endfor %}

log = get_logger()

def add_routes(app, grpc_client):

    pass  # so that if no endpoints are defined, Python is still happy

    {% for method in methods %}
    {% set method_name = method['service'].rpartition('.')[2] + '_' + method['method'] %}
    {% set path = method['path'].replace('{', '<string:').replace('}', '>') %}
    @app.route('{{ path }}', methods=['{{ method['verb'].upper() }}'])
    @inlineCallbacks
    def {{ method_name }}(server, request, **kw):
        log.debug('{{ method_name }}', request=request, server=server, **kw)
        {% if method['body'] == '*' %}
        data = load(request.content)
        data.update(kw)
        {% elif method['body'] == '' %}
        data = kw
        {% else %}
        raise NotImplementedError('cannot handle specific body field list')
        {% endif %}
        try:
            req = ParseDict(data, {{ type_map[method['input_type']] }}())
        except Exception, e:
            log.error('cannot-convert-to-protobuf', e=e, data=data)
            raise
        res, metadata = yield grpc_client.invoke(
            {{ stub_map[method['service']] }}Stub,
            '{{ method['method'] }}', req, request.getAllHeaders().items())
        try:
            out_data = MessageToDict(res, True, True)
        except AttributeError, e:
            filename = '/tmp/chameleon_failed_to_convert_data.pbd'
            with file(filename, 'w') as f:
                f.write(res.SerializeToString())
            log.error('cannot-convert-from-protobuf', outdata_saved=filename)
            raise
        for key, value in metadata:
            request.setHeader(key, value)
        request.setHeader('Content-Type', 'application/json')
        log.debug('{{ method_name }}', **out_data)
        returnValue(dumps(out_data))

    {% endfor %}

""", trim_blocks=True, lstrip_blocks=True)


def traverse_methods(proto_file):

    package = proto_file.name
    for service in proto_file.service:
        assert isinstance(service, ServiceDescriptorProto)

        for method in service.method:
            options = method.options
            assert isinstance(options, MethodOptions)
            for fd, http in options.ListFields():
                if fd.full_name == 'googleapi.http':
                    assert fd.name == 'http'
                    assert isinstance(http, http_pb2.HttpRule)

                    input_type = method.input_type
                    if input_type.startswith('.'):
                        input_type = input_type[1:]

                    output_type = method.output_type
                    if output_type.startswith('.'):
                        output_type = output_type[1:]

                    if http.delete:
                        verb = 'delete'
                        path = http.delete
                    elif http.get:
                        verb = 'get'
                        path = http.get
                    elif http.patch:
                        verb = 'patch'
                        path = http.patch
                    elif http.post:
                        verb = 'post'
                        path = http.post
                    elif http.put:
                        verb = 'put'
                        path = http.put
                    else:
                        raise AttributeError('No valid verb in method %s' %
                                             method.name)

                    body = http.body

                    data = {
                        'package': package,
                        'filename': proto_file.name,
                        'service': proto_file.package + '.' + service.name,
                        'method': method.name,
                        'input_type': input_type,
                        'output_type': output_type,
                        'path': path,
                        'verb': verb,
                        'body': body
                    }

                    yield data


def generate_gw_code(file_name, methods, type_map, stub_map, includes):
    return template.render(file_name=file_name, methods=methods,
                           type_map=type_map, stub_map=stub_map, includes=includes)


class IncludeManager(object):
    # need to keep track of what files define what message types and
    # under what package name. Later, when we analyze the methods, we
    # need to be able to derive the list of files we need to load and we
    # also need to replce the <proto-package-name>.<artifact-name> in the
    # templates with <python-package-name>.<artifact-name> so Python can
    # resolve these.
    def __init__(self):
        self.package_to_localname = {}
        self.fullname_to_filename = {}
        self.prefix_table = []  # sorted table of top-level symbols in protos
        self.type_map = {}  # full name as used in .proto -> python name
        self.stub_map = {}
        self.includes_needed = set()  # names of files needed to be included
        self.filename_to_module = {}  # filename -> (package, module)

    def extend_symbol_tables(self, proto_file):
        # keep track of what file adds what top-level symbol to what abstract
        # package name
        package_name = proto_file.package
        file_name = proto_file.name
        self._add_filename(file_name)
        all_defs = list(proto_file.message_type)
        all_defs.extend(list(proto_file.enum_type))
        all_defs.extend(list(proto_file.service))
        for typedef in all_defs:
            name = typedef.name
            fullname = package_name + '.' + name
            self.fullname_to_filename[fullname] = file_name
            self.package_to_localname.setdefault(package_name, []).append(name)
        self._update_prefix_table()

    def _add_filename(self, filename):
        if filename not in self.filename_to_module:
            python_path = filename.replace('.proto', '_pb2').replace('/', '.')
            package_name, _, module_name = python_path.rpartition('.')
            self.filename_to_module[filename] = (package_name, module_name)

    def _update_prefix_table(self):
        # make a sorted list symbol prefixes needed to resolv for potential use
        # of nested symbols
        self.prefix_table = sorted(self.fullname_to_filename.iterkeys(),
                                   reverse=True)

    def _find_matching_prefix(self, fullname):
        for prefix in self.prefix_table:
            if fullname.startswith(prefix):
                return prefix
        # This should never happen
        raise Exception('No match for type name "{}"'.format(fullname))

    def add_needed_symbol(self, fullname):
        if fullname in self.type_map:
            return
        top_level_symbol = self._find_matching_prefix(fullname)
        name = top_level_symbol.rpartition('.')[2]
        nested_name = fullname[len(top_level_symbol):]  # may be empty
        file_name = self.fullname_to_filename[top_level_symbol]
        self.includes_needed.add(file_name)
        module_name = self.filename_to_module[file_name][1]
        python_name = module_name + '.' + name + nested_name
        self.type_map[fullname] = python_name
        python_name = module_name + '_grpc.' + name + nested_name
        self.stub_map[fullname] = python_name

    def get_type_map(self):
        return self.type_map

    def get_stub_map(self):
        return self.stub_map

    def get_includes(self):
        return sorted(
            self.filename_to_module[fn] for fn in self.includes_needed)


def generate_code(request, response):

    assert isinstance(request, plugin.CodeGeneratorRequest)

    include_manager = IncludeManager()
    for proto_file in request.proto_file:

        include_manager.extend_symbol_tables(proto_file)

        methods = []

        for data in traverse_methods(proto_file):
            methods.append(data)
            include_manager.add_needed_symbol(data['input_type'])
            include_manager.add_needed_symbol(data['output_type'])
            include_manager.add_needed_symbol(data['service'])

        type_map = include_manager.get_type_map()
        stub_map = include_manager.get_stub_map()
        includes = include_manager.get_includes()

        # as a nice side-effect, generate a json file capturing the essence
        # of the RPC method entries
        f = response.file.add()
        f.name = proto_file.name + '.json'
        f.content = dumps(dict(
            type_rename_map=type_map,  # TODO: is stub_map needed here?
            includes=includes,
            methods=methods), indent=4)

        # generate the real Python code file
        f = response.file.add()
        assert proto_file.name.endswith('.proto')
        f.name = proto_file.name.replace('.proto', '_gw.py')
        f.content = generate_gw_code(proto_file.name,
                                     methods, type_map, stub_map, includes)


if __name__ == '__main__':

    if len(sys.argv) >= 2:
        # read input from file, to allow troubleshooting
        with open(sys.argv[1], 'r') as f:
            data = f.read()
    else:
        # read input from stdin
        data = sys.stdin.read()
        # with file('/tmp/buf', 'wb') as f:
        #     f.write(data)

    # parse request
    request = plugin.CodeGeneratorRequest()
    request.ParseFromString(data)

    # create response object
    response = plugin.CodeGeneratorResponse()

    # generate the output and the response
    generate_code(request, response)

    # serialize the response
    output = response.SerializeToString()

    # write response to stdout
    sys.stdout.write(output)
