#!/usr/bin/env python3
#  Copyright 2016 Google Inc. All Rights Reserved.
#
# 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 pytest

from fruit_test_common import *

COMMON_DEFINITIONS = '''
    #include "test_common.h"

    struct Annotation1 {};
    struct Annotation2 {};

    template <typename T>
    using WithNoAnnot = T;

    template <typename T>
    using WithAnnot1 = fruit::Annotated<Annotation1, T>;

    template <typename T>
    using WithAnnot2 = fruit::Annotated<Annotation2, T>;
    '''

@pytest.mark.parametrize('IAnnot,XAnnot,WithAnnot', [
    ('I', 'X', 'WithNoAnnot'),
    ('fruit::Annotated<Annotation1, I>', 'fruit::Annotated<Annotation2, X>', 'WithAnnot1'),
])
def test_provider_returning_value_success_with_annotation(IAnnot, XAnnot, WithAnnot):
    source = '''
        struct I {
          int value = 5;
        };

        struct X : public I, ConstructionTracker<X> {
        };

        fruit::Component<IAnnot> getComponent() {
          return fruit::createComponent()
            .registerProvider<XAnnot()>([](){return X();})
            .bind<IAnnot, XAnnot>();
        }

        int main() {
          fruit::Injector<IAnnot> injector(getComponent());
          Assert((injector.get<WithAnnot<I                 >>() .value == 5));
          Assert((injector.get<WithAnnot<I*                >>()->value == 5));
          Assert((injector.get<WithAnnot<I&                >>() .value == 5));
          Assert((injector.get<WithAnnot<const I           >>() .value == 5));
          Assert((injector.get<WithAnnot<const I*          >>()->value == 5));
          Assert((injector.get<WithAnnot<const I&          >>() .value == 5));
          Assert((injector.get<WithAnnot<std::shared_ptr<I>>>()->value == 5));
          Assert(injector.unsafeGet<WithAnnot<X>>() == nullptr);

          Assert(X::num_objects_constructed == 1);
        }
        '''
    expect_success(
        COMMON_DEFINITIONS,
        source,
        locals())

@pytest.mark.parametrize('IAnnot,XAnnot,XPtrAnnot,WithAnnot', [
    ('I', 'X', 'X*', 'WithNoAnnot'),
    ('fruit::Annotated<Annotation1, I>', 'fruit::Annotated<Annotation2, X>', 'fruit::Annotated<Annotation2, X*>', 'WithAnnot1'),
])
def test_provider_returning_pointer_success_with_annotation(IAnnot, XAnnot, XPtrAnnot, WithAnnot):
    source = '''
        struct I {
          int value = 5;
        };

        struct X : public I, ConstructionTracker<X> {
        };

        fruit::Component<IAnnot> getComponent() {
          return fruit::createComponent()
            .registerProvider<XPtrAnnot()>([](){return new X();})
            .bind<IAnnot, XAnnot>();
        }

        int main() {
          fruit::Injector<IAnnot> injector(getComponent());
          Assert((injector.get<WithAnnot<I                 >>() .value == 5));
          Assert((injector.get<WithAnnot<I*                >>()->value == 5));
          Assert((injector.get<WithAnnot<I&                >>() .value == 5));
          Assert((injector.get<WithAnnot<const I           >>() .value == 5));
          Assert((injector.get<WithAnnot<const I*          >>()->value == 5));
          Assert((injector.get<WithAnnot<const I&          >>() .value == 5));
          Assert((injector.get<WithAnnot<std::shared_ptr<I>>>()->value == 5));
          Assert(injector.unsafeGet<WithAnnot<X>>() == nullptr);
          Assert(X::num_objects_constructed == 1);
        }
        '''
    expect_success(
        COMMON_DEFINITIONS,
        source,
        locals())

def test_compression_undone():
    source = '''
        struct I1 {};
        struct C1 : public I1, ConstructionTracker<C1> {
          INJECT(C1()) = default;
        };

        struct I2 {};
        struct C2 : public I2 {
          INJECT(C2(I1*)) {}
        };

        fruit::Component<I1> getI1Component() {
          return fruit::createComponent()
              .bind<I1, C1>();
        }

        fruit::Component<I2> getI2Component() {
          return fruit::createComponent()
              .install(getI1Component())
              .bind<I2, C2>();
        }

        struct X {
          // Intentionally C1 and not I1. This prevents binding compression for the I1->C1 edge.
          INJECT(X(C1*)) {}
        };

        fruit::Component<X> getXComponent() {
          return fruit::createComponent();
        }

        int main() {
          // Here the binding C2->I1->C1 is compressed into C2->C1.
          fruit::NormalizedComponent<I2> normalizedComponent(getI2Component());

          // However the binding X->C1 prevents binding compression on I1->C1, the binding compression must be undone.
          fruit::Injector<I2, X> injector(normalizedComponent, getXComponent());

          Assert(C1::num_objects_constructed == 0);
          injector.get<I2*>();
          injector.get<X*>();
          Assert(injector.unsafeGet<C1>() != nullptr);
          Assert(C1::num_objects_constructed == 1);
        }
        '''
    expect_success(
        COMMON_DEFINITIONS,
        source)

if __name__== '__main__':
    main(__file__)
