/*
 * Copyright 2021 VMware, 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
 *
 * https://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.
 */
package io.micrometer.observation;

import io.micrometer.observation.ObservationHandler.AllMatchingCompositeObservationHandler;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;

class AllMatchingCompositeObservationHandlerTests {

    MatchingHandler matchingHandler = new MatchingHandler();

    MatchingHandler matchingHandler2 = new MatchingHandler();

    @Test
    void should_run_on_start_for_all_matching_handlers() {
        AllMatchingCompositeObservationHandler allMatchingHandler = new AllMatchingCompositeObservationHandler(
                new NotMatchingHandler(), this.matchingHandler, new NotMatchingHandler(), this.matchingHandler2);

        allMatchingHandler.onStart(null);

        Assertions.assertThat(this.matchingHandler.started).isTrue();
        Assertions.assertThat(this.matchingHandler2.started).isTrue();
    }

    @Test
    void should_run_on_stop_for_all_matching_handlers() {
        AllMatchingCompositeObservationHandler allMatchingHandler = new AllMatchingCompositeObservationHandler(
                new NotMatchingHandler(), this.matchingHandler, new NotMatchingHandler(), this.matchingHandler2);

        allMatchingHandler.onStop(null);

        Assertions.assertThat(this.matchingHandler.stopped).isTrue();
        Assertions.assertThat(this.matchingHandler2.stopped).isTrue();
    }

    @Test
    void should_run_on_error_for_all_matching_handlers() {
        AllMatchingCompositeObservationHandler allMatchingHandler = new AllMatchingCompositeObservationHandler(
                new NotMatchingHandler(), this.matchingHandler, new NotMatchingHandler(), this.matchingHandler2);

        allMatchingHandler.onError(null);

        Assertions.assertThat(this.matchingHandler.errored).isTrue();
        Assertions.assertThat(this.matchingHandler2.errored).isTrue();
    }

    @Test
    void should_run_on_scope_opened_for_all_matching_handlers() {
        AllMatchingCompositeObservationHandler allMatchingHandler = new AllMatchingCompositeObservationHandler(
                new NotMatchingHandler(), this.matchingHandler, new NotMatchingHandler(), this.matchingHandler2);

        allMatchingHandler.onScopeOpened(null);

        Assertions.assertThat(this.matchingHandler.scopeOpened).isTrue();
        Assertions.assertThat(this.matchingHandler2.scopeOpened).isTrue();
    }

    @Test
    void should_run_on_scope_closed_for_all_matching_handlers() {
        AllMatchingCompositeObservationHandler allMatchingHandler = new AllMatchingCompositeObservationHandler(
                new NotMatchingHandler(), this.matchingHandler, new NotMatchingHandler(), this.matchingHandler2);

        allMatchingHandler.onScopeClosed(null);

        Assertions.assertThat(this.matchingHandler.scopeClosed).isTrue();
        Assertions.assertThat(this.matchingHandler2.scopeClosed).isTrue();
    }

    @Test
    void should_support_the_context_if_any_handler_supports_it() {
        AllMatchingCompositeObservationHandler allMatchingHandler = new AllMatchingCompositeObservationHandler(
                new NotMatchingHandler(), this.matchingHandler, new NotMatchingHandler(), this.matchingHandler2);
        Assertions.assertThat(allMatchingHandler.supportsContext(new Observation.Context())).isTrue();
    }

    @Test
    void should_return_observation_handlers() {
        List<ObservationHandler<? extends Observation.Context>> handlers = new ArrayList<>();
        handlers.add(new NotMatchingHandler());
        handlers.add(this.matchingHandler);
        handlers.add(new NotMatchingHandler());
        handlers.add(this.matchingHandler2);
        AllMatchingCompositeObservationHandler allMatchingHandler = new AllMatchingCompositeObservationHandler(
                handlers);
        Assertions.assertThat(allMatchingHandler.getHandlers()).isEqualTo(handlers);
    }

    @Test
    void should_return_custom_handlers() {
        List<NotMatchingHandler> handlers = new ArrayList<>();
        handlers.add(new NotMatchingHandler());
        handlers.add(new NotMatchingHandler());
        AllMatchingCompositeObservationHandler allMatchingHandler = new AllMatchingCompositeObservationHandler(
                handlers);
        Assertions.assertThat(allMatchingHandler.getHandlers()).isEqualTo(handlers);
    }

    static class MatchingHandler implements ObservationHandler<Observation.Context> {

        boolean started;

        boolean stopped;

        boolean errored;

        boolean scopeOpened;

        boolean scopeClosed;

        @Override
        public void onStart(Observation.Context context) {
            this.started = true;
        }

        @Override
        public void onError(Observation.Context context) {
            this.errored = true;
        }

        @Override
        public void onScopeOpened(Observation.Context context) {
            this.scopeOpened = true;
        }

        @Override
        public void onScopeClosed(Observation.Context context) {
            this.scopeClosed = true;
        }

        @Override
        public void onStop(Observation.Context context) {
            this.stopped = true;
        }

        @Override
        public boolean supportsContext(Observation.Context context) {
            return true;
        }

    }

    static class NotMatchingHandler implements ObservationHandler<CustomContext> {

        @Override
        public void onStart(CustomContext context) {
            throwAssertionError();
        }

        @Override
        public void onError(CustomContext context) {
            throwAssertionError();
        }

        @Override
        public void onScopeOpened(CustomContext context) {
            throwAssertionError();
        }

        @Override
        public void onStop(CustomContext context) {
            throwAssertionError();
        }

        @Override
        public boolean supportsContext(Observation.Context context) {
            return false;
        }

        private void throwAssertionError() {
            throw new AssertionError("Not matching handler must not be called");
        }

    }

    static class CustomContext extends Observation.Context {

    }

}

@@ -718,48 +718,8 @@
 er;%0A
-import org.assertj.core.api.Assertions;%0A
 impo
@@ -802,16 +802,75 @@
 .List;%0A%0A
+import static org.assertj.core.api.Assertions.assertThat;%0A%0A
 class Al
@@ -1382,35 +1382,24 @@
 );%0A%0A        
-Assertions.
 assertThat(t
@@ -1441,35 +1441,24 @@
 ();%0A        
-Assertions.
 assertThat(t
@@ -1845,35 +1845,24 @@
 );%0A%0A        
-Assertions.
 assertThat(t
@@ -1904,35 +1904,24 @@
 ();%0A        
-Assertions.
 assertThat(t
@@ -2310,35 +2310,24 @@
 );%0A%0A        
-Assertions.
 assertThat(t
@@ -2369,35 +2369,24 @@
 ();%0A        
-Assertions.
 assertThat(t
@@ -2788,35 +2788,24 @@
 );%0A%0A        
-Assertions.
 assertThat(t
@@ -2851,35 +2851,24 @@
 ();%0A        
-Assertions.
 assertThat(t
@@ -3274,35 +3274,24 @@
 );%0A%0A        
-Assertions.
 assertThat(t
@@ -3337,35 +3337,24 @@
 ();%0A        
-Assertions.
 assertThat(t
@@ -3711,35 +3711,24 @@
 2);%0A        
-Assertions.
 assertThat(a
@@ -4286,35 +4286,24 @@
 s);%0A        
-Assertions.
 assertThat(a
@@ -4722,27 +4722,16 @@
         
-Assertions.
 assertTh

Use static import for Assertions.assertThat (#3187)