/*
 * Copyright 2019, TeamDev. All rights reserved.
 *
 * Redistribution and use in source and/or binary forms, with or without
 * modification, must retain the above copyright notice and the following
 * disclaimer.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package io.spine.logging;

import com.google.common.flogger.FluentLogger;
import com.google.common.flogger.LogContext;
import com.google.common.flogger.LoggerConfig;
import com.google.common.flogger.backend.LogData;
import com.google.common.truth.DefaultSubject;
import com.google.common.truth.Subject;
import io.spine.logging.given.LoggingObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.helpers.SubstituteLogger;

import java.util.function.Supplier;
import java.util.logging.Level;

import static io.spine.testing.logging.LogTruth.assertThat;

@DisplayName("Logging interface should")
class LoggingTest {

    @Test
    @DisplayName("assume `Level.FINE` for debug")
    void debugLevel() {
        assertThat(Logging.debugLevel())
             .isEqualTo(Level.FINE);
    }

    @Test
    @DisplayName("assume `Level.SEVER` for errors")
    void errorLevel() {
        assertThat(Logging.errorLevel())
                .isEqualTo(Level.SEVERE);
    }

    @Test
    @DisplayName("obtain Slf4J `Logger` instance")
    void loggerInstance() {
        Logging object = new LoggingObject();
        Logger logger = object.log();
        Subject<DefaultSubject, Object> assertLogger = assertThat(logger);

        assertLogger.isNotNull();
        assertLogger.isInstanceOf(SubstituteLogger.class);
    }

    @Test
    @DisplayName("obtain same `FluentLogger` Instance")
    void fluentLogger() {
        Logging object = new LoggingObject();

        FluentLogger logger = object.logger();

        assertThat(object.logger())
             .isSameInstanceAs(logger);
        assertThat(new LoggingObject().logger())
             .isSameInstanceAs(logger);
    }

    @Nested
    @DisplayName("expose shortcut methods")
    class Shortcuts {

        private Logging object;
        private FluentLogger logger;

        @BeforeEach
        void createLoggingObject() {
            object = new LoggingObject();
            logger = object.logger();
        }

        @Test
        @DisplayName("for standard logging levels")
        void shortcutMethods() {
            assertApi(object::_config, Level.CONFIG);
            assertApi(object::_fine, Level.FINE);
            assertApi(object::_finer, Level.FINER);
            assertApi(object::_finest, Level.FINEST);
            assertApi(object::_info, Level.INFO);
            assertApi(object::_severe, Level.SEVERE);
            assertApi(object::_warn, Level.WARNING);
        }

        @Test
        @DisplayName("for popular aliases")
        void aliases() {
            assertApi(object::_debug, Level.FINE);
            assertApi(object::_trace, Level.FINEST);
            assertApi(object::_error, Level.SEVERE);
        }

        void assertApi(Supplier<FluentLogger.Api> method,
                            Level expectedLevel) {
            LoggerConfig.of(logger)
                        .setLevel(expectedLevel);

            FluentLogger.Api api = method.get();
            assertThat(api)
                    .isInstanceOf(LogContext.class);
            assertThat(((LogData) api).getLevel())
                    .isEqualTo(expectedLevel);
        }
    }
}

@@ -1226,95 +1226,8 @@
 ta;%0A
-import com.google.common.truth.DefaultSubject;%0Aimport com.google.common.truth.Subject;%0A
 impo
@@ -1267,16 +1267,16 @@
 Object;%0A
+
 import o
@@ -1425,76 +1425,8 @@
 est;
-%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.helpers.SubstituteLogger;
 %0A%0Aim
@@ -1903,32 +1903,32 @@
 g.errorLevel())%0A
+
                 
@@ -1964,357 +1964,8 @@
  %7D%0A%0A
-    @Test%0A    @DisplayName(%22obtain Slf4J %60Logger%60 instance%22)%0A    void loggerInstance() %7B%0A        Logging object = new LoggingObject();%0A        Logger logger = object.log();%0A        Subject%3CDefaultSubject, Object%3E assertLogger = assertThat(logger);%0A%0A        assertLogger.isNotNull();%0A        assertLogger.isInstanceOf(SubstituteLogger.class);%0A    %7D%0A%0A
     

Address deprecations