# Copyright The OpenTelemetry 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 os
from logging import getLogger
from os import environ
from typing import Sequence, Tuple

from pkg_resources import iter_entry_points

from opentelemetry import trace
from opentelemetry.environment_variables import (
    OTEL_PYTHON_ID_GENERATOR,
    OTEL_PYTHON_SERVICE_NAME,
    OTEL_TRACES_EXPORTER,
)
from opentelemetry.instrumentation.configurator import BaseConfigurator
from opentelemetry.instrumentation.distro import BaseDistro
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor, SpanExporter
from opentelemetry.sdk.trace.id_generator import IdGenerator

logger = getLogger(__file__)


EXPORTER_OTLP = "otlp"
EXPORTER_OTLP_SPAN = "otlp_span"

RANDOM_ID_GENERATOR = "random"
_DEFAULT_ID_GENERATOR = RANDOM_ID_GENERATOR


def _get_id_generator() -> str:
    return environ.get(OTEL_PYTHON_ID_GENERATOR, _DEFAULT_ID_GENERATOR)


def _get_service_name() -> str:
    return environ.get(OTEL_PYTHON_SERVICE_NAME, "")


def _get_exporter_names() -> Sequence[str]:
    trace_exporters = environ.get(OTEL_TRACES_EXPORTER)

    exporters = set()

    if (
        trace_exporters is not None
        or trace_exporters.lower().strip() != "none"
    ):
        exporters.update(
            {
                trace_exporter.strip()
                for trace_exporter in trace_exporters.split(",")
            }
        )

    if EXPORTER_OTLP in exporters:
        exporters.pop(EXPORTER_OTLP)
        exporters.add(EXPORTER_OTLP_SPAN)

    return list(exporters)


def _init_tracing(
    exporters: Sequence[SpanExporter], id_generator: IdGenerator
):
    service_name = _get_service_name()
    provider = TracerProvider(
        resource=Resource.create({"service.name": service_name}),
        id_generator=id_generator(),
    )
    trace.set_tracer_provider(provider)

    for exporter_name, exporter_class in exporters.items():
        exporter_args = {}
        if exporter_name not in [
            EXPORTER_OTLP,
            EXPORTER_OTLP_SPAN,
        ]:
            exporter_args["service_name"] = service_name

        provider.add_span_processor(
            BatchSpanProcessor(exporter_class(**exporter_args))
        )


def _import_tracer_provider_config_components(
    selected_components, entry_point_name
) -> Sequence[Tuple[str, object]]:
    component_entry_points = {
        ep.name: ep for ep in iter_entry_points(entry_point_name)
    }
    component_impls = []
    for selected_component in selected_components:
        entry_point = component_entry_points.get(selected_component, None)
        if not entry_point:
            raise RuntimeError(
                "Requested component '{}' not found in entry points for '{}'".format(
                    selected_component, entry_point_name
                )
            )

        component_impl = entry_point.load()
        component_impls.append((selected_component, component_impl))

    return component_impls


def _import_exporters(
    exporter_names: Sequence[str],
) -> Sequence[SpanExporter]:
    trace_exporters = {}

    for (
        exporter_name,
        exporter_impl,
    ) in _import_tracer_provider_config_components(
        exporter_names, "opentelemetry_exporter"
    ):
        if issubclass(exporter_impl, SpanExporter):
            trace_exporters[exporter_name] = exporter_impl
        else:
            raise RuntimeError(
                "{0} is not a trace exporter".format(exporter_name)
            )
    return trace_exporters


def _import_id_generator(id_generator_name: str) -> IdGenerator:
    # pylint: disable=unbalanced-tuple-unpacking
    [
        (id_generator_name, id_generator_impl)
    ] = _import_tracer_provider_config_components(
        [id_generator_name.strip()], "opentelemetry_id_generator"
    )

    if issubclass(id_generator_impl, IdGenerator):
        return id_generator_impl

    raise RuntimeError("{0} is not an IdGenerator".format(id_generator_name))


def _initialize_components():
    exporter_names = _get_exporter_names()
    trace_exporters = _import_exporters(exporter_names)
    id_generator_name = _get_id_generator()
    id_generator = _import_id_generator(id_generator_name)
    _init_tracing(trace_exporters, id_generator)


class Configurator(BaseConfigurator):
    def _configure(self, **kwargs):
        _initialize_components()


class OpenTelemetryDistro(BaseDistro):
    """
    The OpenTelemetry provided Distro configures a default set of
    configuration out of the box.
    """

    def _configure(self, **kwargs):
        os.environ.setdefault(OTEL_TRACES_EXPORTER, "otlp_span")

opentelemetry-distro/src/opentelemetry/distro/__init__.py
# Copyright The OpenTelemetry 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 os
from logging import getLogger
from os import environ
from typing import Sequence, Tuple

from pkg_resources import iter_entry_points

from opentelemetry import trace
from opentelemetry.environment_variables import (
    OTEL_PYTHON_ID_GENERATOR,
    OTEL_PYTHON_SERVICE_NAME,
    OTEL_TRACES_EXPORTER,
)
from opentelemetry.instrumentation.configurator import BaseConfigurator
from opentelemetry.instrumentation.distro import BaseDistro
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor, SpanExporter
from opentelemetry.sdk.trace.id_generator import IdGenerator

logger = getLogger(__file__)


EXPORTER_OTLP = "otlp"
EXPORTER_OTLP_SPAN = "otlp_span"

RANDOM_ID_GENERATOR = "random"
_DEFAULT_ID_GENERATOR = RANDOM_ID_GENERATOR


def _get_id_generator() -> str:
    return environ.get(OTEL_PYTHON_ID_GENERATOR, _DEFAULT_ID_GENERATOR)


def _get_service_name() -> str:
    return environ.get(OTEL_PYTHON_SERVICE_NAME, "")


def _get_exporter_names() -> Sequence[str]:
    trace_exporters = environ.get(OTEL_TRACES_EXPORTER)

    exporters = set()

    if (
        trace_exporters is not None
        or trace_exporters.lower().strip() != "none"
    ):
        exporters.update(
            {
                trace_exporter.strip()
                for trace_exporter in trace_exporters.split(",")
            }
        )

    if EXPORTER_OTLP in exporters:
        exporters.remove(EXPORTER_OTLP)
        exporters.add(EXPORTER_OTLP_SPAN)

    return list(exporters)


def _init_tracing(
    exporters: Sequence[SpanExporter], id_generator: IdGenerator
):
    service_name = _get_service_name()
    provider = TracerProvider(
        resource=Resource.create({"service.name": service_name}),
        id_generator=id_generator(),
    )
    trace.set_tracer_provider(provider)

    for exporter_name, exporter_class in exporters.items():
        exporter_args = {}
        if exporter_name not in [
            EXPORTER_OTLP,
            EXPORTER_OTLP_SPAN,
        ]:
            exporter_args["service_name"] = service_name

        provider.add_span_processor(
            BatchSpanProcessor(exporter_class(**exporter_args))
        )


def _import_tracer_provider_config_components(
    selected_components, entry_point_name
) -> Sequence[Tuple[str, object]]:
    component_entry_points = {
        ep.name: ep for ep in iter_entry_points(entry_point_name)
    }
    component_impls = []
    for selected_component in selected_components:
        entry_point = component_entry_points.get(selected_component, None)
        if not entry_point:
            raise RuntimeError(
                "Requested component '{}' not found in entry points for '{}'".format(
                    selected_component, entry_point_name
                )
            )

        component_impl = entry_point.load()
        component_impls.append((selected_component, component_impl))

    return component_impls


def _import_exporters(
    exporter_names: Sequence[str],
) -> Sequence[SpanExporter]:
    trace_exporters = {}

    for (
        exporter_name,
        exporter_impl,
    ) in _import_tracer_provider_config_components(
        exporter_names, "opentelemetry_exporter"
    ):
        if issubclass(exporter_impl, SpanExporter):
            trace_exporters[exporter_name] = exporter_impl
        else:
            raise RuntimeError(
                "{0} is not a trace exporter".format(exporter_name)
            )
    return trace_exporters


def _import_id_generator(id_generator_name: str) -> IdGenerator:
    # pylint: disable=unbalanced-tuple-unpacking
    [
        (id_generator_name, id_generator_impl)
    ] = _import_tracer_provider_config_components(
        [id_generator_name.strip()], "opentelemetry_id_generator"
    )

    if issubclass(id_generator_impl, IdGenerator):
        return id_generator_impl

    raise RuntimeError("{0} is not an IdGenerator".format(id_generator_name))


def _initialize_components():
    exporter_names = _get_exporter_names()
    trace_exporters = _import_exporters(exporter_names)
    id_generator_name = _get_id_generator()
    id_generator = _import_id_generator(id_generator_name)
    _init_tracing(trace_exporters, id_generator)


class Configurator(BaseConfigurator):
    def _configure(self, **kwargs):
        _initialize_components()


class OpenTelemetryDistro(BaseDistro):
    """
    The OpenTelemetry provided Distro configures a default set of
    configuration out of the box.
    """

    def _configure(self, **kwargs):
        os.environ.setdefault(OTEL_TRACES_EXPORTER, "otlp_span")

opentelemetry-distro/src/opentelemetry/distro/__init__.py
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 81c56db3798..47db7726653 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -22,6 +22,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
   ([#1656])(https://github.com/open-telemetry/opentelemetry-python/pull/1656)
 - Rename `DefaultSpan` to `NonRecordingSpan`
   ([#1661])(https://github.com/open-telemetry/opentelemetry-python/pull/1661)
+- Fixed distro configuration with `OTEL_TRACES_EXPORTER` env var set to `otlp`
+  ([#1657])(https://github.com/open-telemetry/opentelemetry-python/pull/1657)
 - Moving `Getter`, `Setter` and `TextMapPropagator` out of `opentelemetry.trace.propagation` and
   into `opentelemetry.propagators`
   ([#1662])(https://github.com/open-telemetry/opentelemetry-python/pull/1662)
diff --git a/opentelemetry-distro/src/opentelemetry/distro/__init__.py b/opentelemetry-distro/src/opentelemetry/distro/__init__.py
index 666ab57bb37..6496be16c5b 100644
--- a/opentelemetry-distro/src/opentelemetry/distro/__init__.py
+++ b/opentelemetry-distro/src/opentelemetry/distro/__init__.py
@@ -67,7 +67,7 @@ def _get_exporter_names() -> Sequence[str]:
         )
 
     if EXPORTER_OTLP in exporters:
-        exporters.pop(EXPORTER_OTLP)
+        exporters.remove(EXPORTER_OTLP)
         exporters.add(EXPORTER_OTLP_SPAN)
 
     return list(exporters)
diff --git a/opentelemetry-distro/tests/test_configurator.py b/opentelemetry-distro/tests/test_configurator.py
index 91ca82da86f..899e019113c 100644
--- a/opentelemetry-distro/tests/test_configurator.py
+++ b/opentelemetry-distro/tests/test_configurator.py
@@ -18,6 +18,9 @@
 from unittest.mock import patch
 
 from opentelemetry.distro import (
+    EXPORTER_OTLP,
+    EXPORTER_OTLP_SPAN,
+    _get_exporter_names,
     _get_id_generator,
     _import_id_generator,
     _init_tracing,
@@ -25,6 +28,7 @@
 from opentelemetry.environment_variables import (
     OTEL_PYTHON_ID_GENERATOR,
     OTEL_PYTHON_SERVICE_NAME,
+    OTEL_TRACES_EXPORTER,
 )
 from opentelemetry.sdk.resources import Resource
 from opentelemetry.sdk.trace.id_generator import IdGenerator, RandomIdGenerator
@@ -143,3 +147,14 @@ def test_trace_init_custom_id_generator(self, mock_iter_entry_points):
         _init_tracing({}, id_generator)
         provider = self.set_provider_mock.call_args[0][0]
         self.assertIsInstance(provider.id_generator, CustomIdGenerator)
+
+
+class TestExporterNames(TestCase):
+    def test_otlp_exporter_overwrite(self):
+        for exporter in [EXPORTER_OTLP, EXPORTER_OTLP_SPAN]:
+            with patch.dict(environ, {OTEL_TRACES_EXPORTER: exporter}):
+                self.assertEqual(_get_exporter_names(), [EXPORTER_OTLP_SPAN])
+
+    @patch.dict(environ, {OTEL_TRACES_EXPORTER: "jaeger,zipkin"})
+    def test_multiple_exporters(self):
+        self.assertEqual(sorted(_get_exporter_names()), ["jaeger", "zipkin"])

TypeError: pop() takes no arguments (1 given) with otlp exporter 0.18b0
**Describe your environment** 
opentelemetry-sdk==1.0.0rc1
opentelemetry-exporter-otlp==1.0.0rc1
opentelemetry-exporter-jaeger==1.0.0rc1
opentelemetry-propagator-b3==1.0.0rc1
opentelemetry-distro==0.18b0
opentelemetry-instrumentation==0.18b0
opentelemetry-instrumentation-grpc==0.18b0
opentelemetry-instrumentation-jinja2==0.18b0

export OTEL_TRACES_EXPORTER="otlp"
export OTEL_EXPORTER_OTLP_INSECURE=true
export OTEL_EXPORTER_OTLP_ENDPOINT="markf-0398:4317"
export OTEL_RESOURCE_ATTRIBUTES="service.name=emailservice, environment=hipster_shop"

**Steps to reproduce**
I'm using this app, but I don't believe it makes any difference, given the error.
https://github.com/markfink-splunk/microservices-demo/tree/master/src/emailservice

**What is the expected behavior?**
otlp should initialize and export traces.

**What is the actual behavior?**
I get this error immediately upon executing "opentelemetry-instrument python email_server.py".

Configuration of configurator failed
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py", line 74, in _load_configurators
    entry_point.load()().configure()  # type: ignore
  File "/usr/local/lib/python3.7/site-packages/opentelemetry/instrumentation/configurator.py", line 50, in configure
    self._configure(**kwargs)
  File "/usr/local/lib/python3.7/site-packages/opentelemetry/distro/__init__.py", line 168, in _configure
    _initialize_components()
  File "/usr/local/lib/python3.7/site-packages/opentelemetry/distro/__init__.py", line 159, in _initialize_components
    exporter_names = _get_exporter_names()
  File "/usr/local/lib/python3.7/site-packages/opentelemetry/distro/__init__.py", line 73, in _get_exporter_names
    exporters.pop(EXPORTER_OTLP)
TypeError: pop() takes no arguments (1 given)
Failed to auto initialize opentelemetry
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py", line 84, in initialize
    _load_configurators()
  File "/usr/local/lib/python3.7/site-packages/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py", line 78, in _load_configurators
    raise exc
  File "/usr/local/lib/python3.7/site-packages/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py", line 74, in _load_configurators
    entry_point.load()().configure()  # type: ignore
  File "/usr/local/lib/python3.7/site-packages/opentelemetry/instrumentation/configurator.py", line 50, in configure
    self._configure(**kwargs)
  File "/usr/local/lib/python3.7/site-packages/opentelemetry/distro/__init__.py", line 168, in _configure
    _initialize_components()
  File "/usr/local/lib/python3.7/site-packages/opentelemetry/distro/__init__.py", line 159, in _initialize_components
    exporter_names = _get_exporter_names()
  File "/usr/local/lib/python3.7/site-packages/opentelemetry/distro/__init__.py", line 73, in _get_exporter_names
    exporters.pop(EXPORTER_OTLP)
TypeError: pop() takes no arguments (1 given)

