package com.github.arteam.jdbi3.strategies;

import com.codahale.metrics.MetricRegistry;
import org.jdbi.v3.core.extension.ExtensionMethod;
import org.jdbi.v3.core.statement.StatementContext;

import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public enum DefaultNameStrategy implements StatementNameStrategy {

    CHECK_EMPTY {
        @Override
        public String getStatementName(StatementContext statementContext) {
            final String rawSql = statementContext.getRawSql();
            if (rawSql == null || rawSql.length() == 0) {
                return SQL_EMPTY;
            }
            return null;
        }
    },
    SQL_OBJECT {
        @Override
        public String getStatementName(StatementContext statementContext) {
            ExtensionMethod extensionMethod = statementContext.getExtensionMethod();
            if (extensionMethod != null) {
                final Class<?> clazz = extensionMethod.getType();
                final Method method = extensionMethod.getMethod();
                final String group = clazz.getPackage().getName();
                final String name = clazz.getSimpleName();
                return MetricRegistry.name(group, name, method.getName());
            }
            return null;
        }
    },

    NAIVE_NAME {
        @Override
        public String getStatementName(StatementContext statementContext) {
            return statementContext.getRawSql();
        }
    },

    CONSTANT_SQL_RAW {
        @Override
        public String getStatementName(StatementContext statementContext) {
            return SQL_RAW;
        }
    },

    CONTEXT_CLASS {
        @Override
        public String getStatementName(StatementContext statementContext) {
            final Object classObj = statementContext.getAttribute(STATEMENT_CLASS);
            final Object nameObj = statementContext.getAttribute(STATEMENT_NAME);

            if (classObj == null || nameObj == null) {
                return null;
            }

            final String className = (String) classObj;
            final String statementName = (String) nameObj;

            final int dotPos = className.lastIndexOf('.');
            if (dotPos == -1) {
                return null;
            }

            return MetricRegistry.name(className.substring(0, dotPos),
                    className.substring(dotPos + 1),
                    statementName);
        }
    },
    CONTEXT_NAME {
        @Override
        public String getStatementName(StatementContext statementContext) {
            final Object groupObj = statementContext.getAttribute(STATEMENT_GROUP);
            final Object typeObj = statementContext.getAttribute(STATEMENT_TYPE);
            final Object nameObj = statementContext.getAttribute(STATEMENT_NAME);

            if (groupObj == null || nameObj == null) {
                return null;
            }

            final String group = (String) groupObj;
            final String statementName = (String) nameObj;

            if (typeObj == null) {
                final Matcher matcher = SHORT_PATTERN.matcher(group);
                if (matcher.matches()) {
                    final String groupName = matcher.group(1);
                    final String typeName = matcher.group(2);
                    return MetricRegistry.name(groupName, typeName, statementName);
                }

                return MetricRegistry.name(group, statementName, "");
            } else {
                final String type = (String) typeObj;
                return MetricRegistry.name(group, type, statementName);
            }
        }
    };

    /**
     * File pattern to shorten the group name.
     */
    private static final Pattern SHORT_PATTERN = Pattern.compile("^(.*?)/(.*?)(-sql)?\\.st(g)?$");

    private static final String SQL_EMPTY = "sql.empty";
    private static final String SQL_RAW = "sql.raw";


    /**
     * Context attribute name for the metric class.
     */
    public static final String STATEMENT_CLASS = "_metric_class";

    /**
     * Context attribute name for the metric group.
     */
    public static final String STATEMENT_GROUP = "_metric_group";

    /**
     * Context attribute name for the metric type.
     */
    public static final String STATEMENT_TYPE = "_metric_type";

    /**
     * Context attribute name for the metric name.
     */
    public static final String STATEMENT_NAME = "_metric_name";

}

@@ -370,16 +370,17 @@
 EMPTY %7B%0A
+%0A
         
@@ -610,25 +610,27 @@
  return 
-SQL_EMPTY
+%22sql.empty%22
 ;%0A      
@@ -1510,16 +1510,17 @@
 L_RAW %7B%0A
+%0A
         
@@ -1624,23 +1624,25 @@
  return 
-SQL_RAW
+%22sql.raw%22
 ;%0A      
@@ -2472,32 +2472,204 @@
  CONTEXT_NAME %7B%0A
+%0A        /**%0A         * File pattern to shorten the group name.%0A         */%0A        private final Pattern shortPattern = Pattern.compile(%22%5E(.*?)/(.*?)(-sql)?%5C%5C.st(g)?$%22);%0A%0A
         @Overrid
@@ -3281,29 +3281,28 @@
 tcher = 
-SHORT_PATTERN
+shortPattern
 .matcher
@@ -3824,16 +3824,16 @@
   %7D%0A
+
     %7D;%0A%0A
     
@@ -3832,283 +3832,8 @@
 %7D;%0A%0A
-    /**%0A     * File pattern to shorten the group name.%0A     */%0A    private static final Pattern SHORT_PATTERN = Pattern.compile(%22%5E(.*?)/(.*?)(-sql)?%5C%5C.st(g)?$%22);%0A%0A    private static final String SQL_EMPTY = %22sql.empty%22;%0A    private static final String SQL_RAW = %22sql.raw%22;%0A%0A%0A
     

Move constants to the respective classes