# Copyright 2010 New Relic, Inc.
#
# 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
import types


import newrelic.api.transaction
import newrelic.api.object_wrapper
import newrelic.common.object_wrapper
import newrelic.api.external_trace


class capture_external_trace():
    def __init__(self, wrapped):
        newrelic.api.object_wrapper.update_wrapper(self, wrapped)
        self._nr_next_object = wrapped
        if not hasattr(self, "_nr_last_object"):
            self._nr_last_object = wrapped

    def __call__(self, url, *args, **kwargs):

        # The URL be a string or a file like object. Pass call
        # through if not a string.

        if not isinstance(url, str):
            return self._nr_next_object(url, *args, **kwargs)

        # Only then wrap the call if it looks like a URL. To
        # work that out need to first do some conversions of
        # accepted 'feed' formats to proper URL format.

        parsed_url = url

        if parsed_url.startswith("feed:http"):
            parsed_url = parsed_url[5:]
        elif parsed_url.startswith("feed:"):
            parsed_url = f"http:{url[5:]}"

        if parsed_url.split(":")[0].lower() in ["http", "https", "ftp"]:
            current_transaction = newrelic.api.transaction.current_transaction()
            if current_transaction:
                trace = newrelic.api.external_trace.ExternalTrace("feedparser", parsed_url, "GET")
                context_manager = trace.__enter__()
                try:
                    result = self._nr_next_object(url, *args, **kwargs)
                except:  # Catch all
                    context_manager.__exit__(*sys.exc_info())
                    raise
                context_manager.__exit__(None, None, None)
                return result
            else:
                return self._nr_next_object(url, *args, **kwargs)
        else:
            return self._nr_next_object(url, *args, **kwargs)

    def __getattr__(self, name):
        return getattr(self._nr_next_object, name)


def instrument(module):
    newrelic.common.object_wrapper.wrap_object(module, "parse", capture_external_trace)
