/**
 * 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.htrace.impl;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.net.URL;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.htrace.core.HTraceConfiguration;
import org.apache.htrace.core.MilliSpan;
import org.apache.htrace.core.Span;
import org.apache.htrace.core.SpanId;
import org.apache.htrace.core.TracerId;
import org.apache.htrace.util.DataDir;
import org.apache.htrace.util.HTracedProcess;
import org.apache.htrace.util.TestUtil;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.http.HttpStatus;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class TestHTracedRESTReceiver {
  private static final Log LOG =
      LogFactory.getLog(TestHTracedRESTReceiver.class);
  private URL restServerUrl;
  private DataDir dataDir;
  HTracedProcess htraced;

  @Before
  public void setUp() throws Exception {
    this.dataDir = new DataDir();
    File tlDir = DataDir.getTopLevelOfCheckout(this.dataDir.getDataDir());
    File pathToHTracedBinary = HTracedProcess.getPathToHTraceBinaryFromTopLevel(tlDir);
    this.htraced = new HTracedProcess(pathToHTracedBinary,
        dataDir.getDataDir(), "localhost");
    this.restServerUrl = new URL("http://" + htraced.getHttpAddr() + "/");
  }

  @After
  public void tearDown() throws Exception {
    if (this.htraced != null) this.htraced.destroy();
  }

  /**
   * Our simple version of htrace configuration for testing.
   */
  private final class TestHTraceConfiguration extends HTraceConfiguration {
    private final URL restServerUrl;
    final static String TRACER_ID = "TestHTracedRESTReceiver";

    public TestHTraceConfiguration(final URL restServerUrl) {
      this.restServerUrl = restServerUrl;
    }

    @Override
    public String get(String key) {
      return null;
    }

    @Override
    public String get(String key, String defaultValue) {
      if (key.equals(HTracedRESTReceiver.HTRACED_REST_URL_KEY)) {
        return this.restServerUrl.toString();
      } else if (key.equals(TracerId.TRACER_ID_KEY)) {
        return TRACER_ID;
      }
      return defaultValue;
    }
  }

  /**
   * Make sure the REST server basically works.
   * @throws Exception
   */
  @Test (timeout = 10000)
  public void testBasicGet() throws Exception {
    HTracedRESTReceiver receiver =
      new HTracedRESTReceiver(new TestHTraceConfiguration(this.restServerUrl));
    HttpClient http = receiver.createHttpClient(60000L, 60000L);
    http.start();
    try {
      // Do basic a GET /server/info against htraced
      ContentResponse response =
        http.GET(restServerUrl + "server/info");
      assertEquals("application/json", response.getMediaType());
      String content = processGET(response);
      assertTrue(content.contains("ReleaseVersion"));
      System.out.println(content);
    } finally {
      http.stop();
      receiver.close();
    }
  }

  private String processGET(final ContentResponse response) {
    assertTrue("" + response.getStatus(), HttpStatus.OK_200 <= response.getStatus() &&
      response.getStatus() <= HttpStatus.NO_CONTENT_204);
    return response.getContentAsString();
  }

  private void testSendingSpansImpl(boolean testClose) throws Exception {
    final HTracedRESTReceiver receiver =
      new HTracedRESTReceiver(new TestHTraceConfiguration(this.restServerUrl));
    final int NUM_SPANS = 3;
    final HttpClient http = receiver.createHttpClient(60000, 60000);
    http.start();
    Span spans[] = new Span[NUM_SPANS];
    for (int i = 0; i < NUM_SPANS; i++) {
      MilliSpan.Builder builder = new MilliSpan.Builder().
          parents(new SpanId[] { new SpanId(1L, 1L) }).
          spanId(new SpanId(1L, i));
      if (i == NUM_SPANS - 1) {
        builder.tracerId("specialTrid");
      }
      spans[i] = builder.build();
    }
    try {
      for (int i = 0; i < NUM_SPANS; i++) {
        LOG.info("receiving " + spans[i].toString());
        receiver.receiveSpan(spans[i]);
      }
      if (testClose) {
        receiver.close();
      } else {
        receiver.startFlushing();
      }
      TestUtil.waitFor(new TestUtil.Supplier<Boolean>() {
        @Override
        public Boolean get() {
          try {
            for (int i = 0; i < NUM_SPANS; i++) {
              // This is what the REST server expects when querying for a
              // span id.
              String findSpan = String.format("span/%s",
                  new SpanId(1L, i).toString());
              ContentResponse response =
                  http.GET(restServerUrl + findSpan);
              String content = processGET(response);
              if ((content == null) || (content.length() == 0)) {
                LOG.info("Failed to find span " + i);
                return false;
              }
              LOG.info("Got " + content + " for span " + i);
              MilliSpan dspan = MilliSpan.fromJson(content);
              assertEquals(new SpanId(1, i).toString(),
                dspan.getSpanId().toString());
              // Every span should have the tracer ID we set in the
              // configuration... except for the last span, which had
              // a custom value set.
              if (i == NUM_SPANS - 1) {
                assertEquals("specialTrid", dspan.getTracerId());
              } else {
                assertEquals(TestHTraceConfiguration.TRACER_ID,
                    dspan.getTracerId());
              }
            }
            return true;
          } catch (Throwable t) {
            LOG.error("Got exception", t);
            return false;
          }
        }
      }, 10, 20000);
    } finally {
      http.stop();
      if (!testClose) {
        receiver.close();
      }
    }
  }

  /**
   * Send 100 spans then confirm they made it in.
   * @throws Exception
   */
  @Test (timeout = 60000)
  public void testSendingSpans() throws Exception {
    testSendingSpansImpl(false);
  }

  /**
   * Test that the REST receiver blocks during shutdown until all spans are sent
   * (or a long timeout elapses).  Otherwise, short-lived client processes will
   * never have a chance to send all their spans and we will have incomplete
   * information.
   */
  @Test (timeout = 60000)
  public void testShutdownBlocksUntilSpanAreSent() throws Exception {
    testSendingSpansImpl(true);
  }
}
