/*
 * Copyright 2016 LINE Corporation
 *
 * LINE Corporation licenses this file to you 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 com.linecorp.armeria.common.logging;

import javax.annotation.Nullable;

import org.slf4j.Logger;

/**
 * Log level.
 */
public enum LogLevel {
    /**
     * TRACE log level.
     */
    TRACE,
    /**
     * DEBUG log level.
     */
    DEBUG,
    /**
     * INFO log level.
     */
    INFO,
    /**
     * WARN log level.
     */
    WARN,
    /**
     * ERROR log level.
     */
    ERROR;

    /**
     * Returns {@code true} if this level is enabled.
     */
    public boolean isEnabled(Logger logger) {
        switch (this) {
            case TRACE:
                return logger.isTraceEnabled();
            case DEBUG:
                return logger.isDebugEnabled();
            case INFO:
                return logger.isInfoEnabled();
            case WARN:
                return logger.isWarnEnabled();
            case ERROR:
                return logger.isErrorEnabled();
            default:
                throw new Error();
        }
    }

    /**
     * Logs a message at this level.
     */
    public void log(Logger logger, String message) {
        switch (this) {
            case TRACE:
                logger.trace(message);
                break;
            case DEBUG:
                logger.debug(message);
                break;
            case INFO:
                logger.info(message);
                break;
            case WARN:
                logger.warn(message);
                break;
            case ERROR:
                logger.error(message);
                break;
            default:
                throw new Error();
        }
    }

    /**
     * Logs a message at this level.
     */
    @SuppressWarnings("MethodParameterNamingConvention")
    public void log(Logger logger, String format, Object arg1) {
        switch (this) {
            case TRACE:
                logger.trace(format, arg1);
                break;
            case DEBUG:
                logger.debug(format, arg1);
                break;
            case INFO:
                logger.info(format, arg1);
                break;
            case WARN:
                logger.warn(format, arg1);
                break;
            case ERROR:
                logger.error(format, arg1);
                break;
            default:
                throw new Error();
        }
    }

    /**
     * Logs a message at this level.
     */
    @SuppressWarnings("MethodParameterNamingConvention")
    public void log(Logger logger, String format, @Nullable Object arg1, @Nullable Object arg2) {
        switch (this) {
            case TRACE:
                logger.trace(format, arg1, arg2);
                break;
            case DEBUG:
                logger.debug(format, arg1, arg2);
                break;
            case INFO:
                logger.info(format, arg1, arg2);
                break;
            case WARN:
                logger.warn(format, arg1, arg2);
                break;
            case ERROR:
                logger.error(format, arg1, arg2);
                break;
            default:
                throw new Error();
        }
    }

    /**
     * Logs a message at this level.
     */
    @SuppressWarnings("MethodParameterNamingConvention")
    public void log(Logger logger, String format,
                    @Nullable Object arg1, @Nullable Object arg2, @Nullable Object arg3) {
        switch (this) {
            case TRACE:
                logger.trace(format, arg1, arg2, arg3);
                break;
            case DEBUG:
                logger.debug(format, arg1, arg2, arg3);
                break;
            case INFO:
                logger.info(format, arg1, arg2, arg3);
                break;
            case WARN:
                logger.warn(format, arg1, arg2, arg3);
                break;
            case ERROR:
                logger.error(format, arg1, arg2, arg3);
                break;
            default:
                throw new Error();
        }
    }
}

@@ -627,17 +627,16 @@
 se.%0A */%0A
-%0A
 package 
@@ -783,24 +783,71 @@
 l %7B%0A    /**%0A
+     * OFF log level.%0A     */%0A    OFF,%0A    /**%0A
      * TRACE
@@ -1210,32 +1210,84 @@
 switch (this) %7B%0A
+            case OFF:%0A                return false;%0A
             case
@@ -1821,32 +1821,77 @@
 switch (this) %7B%0A
+            case OFF:%0A                break;%0A
             case
@@ -2564,32 +2564,77 @@
 switch (this) %7B%0A
+            case OFF:%0A                break;%0A
             case
@@ -3365,32 +3365,77 @@
 switch (this) %7B%0A
+            case OFF:%0A                break;%0A
             case
@@ -4239,32 +4239,77 @@
 switch (this) %7B%0A
+            case OFF:%0A                break;%0A
             case
@@ -4716,32 +4716,32 @@
     case ERROR:%0A
-
                 
@@ -4874,11 +4874,725 @@
  %7D%0A    %7D
+%0A%0A    /**%0A     * Logs a message at this level.%0A     */%0A    public void log(Logger logger, String format, Object... args) %7B%0A        switch (this) %7B%0A            case OFF:%0A                break;%0A            case TRACE:%0A                logger.trace(format, args);%0A                break;%0A            case DEBUG:%0A                logger.debug(format, args);%0A                break;%0A            case INFO:%0A                logger.info(format, args);%0A                break;%0A            case WARN:%0A                logger.warn(format, args);%0A                break;%0A            case ERROR:%0A                logger.error(format, args);%0A                break;%0A            default:%0A                throw new Error();%0A        %7D%0A    %7D
 %0A%7D%0A

Add `LogLevel.OFF` and `log()` method with varargs (#2532)