/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF 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
 *
 *     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.
 */

package org.apache.solr.util.stats;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Timer;
import org.apache.solr.client.solrj.impl.HttpListenerFactory;
import org.apache.solr.metrics.SolrMetricManager;
import org.apache.solr.metrics.SolrMetricProducer;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Result;

import static org.apache.solr.metrics.SolrMetricManager.mkName;

/**
 * A HttpListenerFactory tracks metrics interesting to solr
 * Inspired and partially copied from dropwizard httpclient library
 */
public class InstrumentedHttpListenerFactory implements SolrMetricProducer, HttpListenerFactory {

  public interface NameStrategy {
    String getNameFor(String scope, Request request);
  }

  private static final NameStrategy QUERYLESS_URL_AND_METHOD =
      (scope, request) -> {
        String schemeHostPort = request.getScheme() + "://" + request.getHost() + ":" + request.getPort() + request.getPath();
        return mkName(schemeHostPort + "." + methodNameString(request), scope);
      };

  private static final NameStrategy METHOD_ONLY =
      (scope, request) -> mkName(methodNameString(request), scope);

  private static final NameStrategy HOST_AND_METHOD =
      (scope, request) -> {
        String schemeHostPort = request.getScheme() + "://" + request.getHost() + ":" + request.getPort();
        return mkName(schemeHostPort + "." + methodNameString(request), scope);
      };

  public static final Map<String, NameStrategy> KNOWN_METRIC_NAME_STRATEGIES = new HashMap<>(3);

  static  {
    KNOWN_METRIC_NAME_STRATEGIES.put("queryLessURLAndMethod", QUERYLESS_URL_AND_METHOD);
    KNOWN_METRIC_NAME_STRATEGIES.put("hostAndMethod", HOST_AND_METHOD);
    KNOWN_METRIC_NAME_STRATEGIES.put("methodOnly", METHOD_ONLY);
  }

  protected MetricRegistry metricsRegistry;
  protected SolrMetricManager metricManager;
  protected String registryName;
  protected String scope;
  protected NameStrategy nameStrategy;

  public InstrumentedHttpListenerFactory(NameStrategy nameStrategy) {
    this.nameStrategy = nameStrategy;
  }

  private static String methodNameString(Request request) {
    return request.getMethod().toLowerCase(Locale.ROOT) + ".requests";
  }

  @Override
  public RequestResponseListener get() {
    return new RequestResponseListener() {
      Timer.Context timerContext;

      @Override
      public void onBegin(Request request) {
        if (metricsRegistry != null) {
          timerContext = timer(request).time();
        }
      }

      @Override
      public void onComplete(Result result) {
        if (timerContext != null) {
          timerContext.stop();
        }
      }
    };
  }

  private Timer timer(Request request) {
    return metricsRegistry.timer(nameStrategy.getNameFor(scope, request));
  }

  @Override
  public void initializeMetrics(SolrMetricManager manager, String registry, String tag, String scope) {
    this.metricManager = manager;
    this.registryName = registry;
    this.metricsRegistry = manager.registry(registry);
    this.scope = scope;
  }
}

