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

import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

import java.util.Collection;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Does some stuff and traces it.
 */
public class TraceCreator implements TestRule {
  private final List<SpanReceiver> receivers = new ArrayList<SpanReceiver>();

  public static final String RPC_TRACE_ROOT = "createSampleRpcTrace";
  public static final String THREADED_TRACE_ROOT = "createThreadedTrace";
  public static final String SIMPLE_TRACE_ROOT = "createSimpleTrace";

  public TraceCreator addReceiver(SpanReceiver receiver) {
    Trace.addReceiver(receiver);
    this.receivers.add(receiver);
    return this;
  }

  @Override
  public Statement apply(final Statement base, Description description) {
    return new Statement() {
      @Override
      public void evaluate() throws Throwable {
        try {
          base.evaluate();
          for (SpanReceiver receiver : receivers) {
            receiver.close();
          }
        } finally {
          for (SpanReceiver receiver : receivers) {
            Trace.removeReceiver(receiver);
          }
        }
      }
    };
  }

  public void createSampleRpcTrace() {
    TraceScope s = Trace.startSpan(RPC_TRACE_ROOT, Sampler.ALWAYS);
    try {
      pretendRpcSend();
    } finally {
      s.close();
    }
  }

  public void createSimpleTrace() {
    TraceScope s = Trace.startSpan(SIMPLE_TRACE_ROOT, Sampler.ALWAYS);
    try {
      importantWork1();
    } finally {
      s.close();
    }
  }

  /**
   * Creates the demo trace (will create different traces from call to call).
   */
  public void createThreadedTrace() {
    TraceScope s = Trace.startSpan(THREADED_TRACE_ROOT, Sampler.ALWAYS);
    try {
      Random r = ThreadLocalRandom.current();
      int numThreads = r.nextInt(4) + 1;
      Thread[] threads = new Thread[numThreads];

      for (int i = 0; i < numThreads; i++) {
        threads[i] = new Thread(Trace.wrap(new MyRunnable()));
      }
      for (int i = 0; i < numThreads; i++) {
        threads[i].start();
      }
      for (int i = 0; i < numThreads; i++) {
        try {
          threads[i].join();
        } catch (InterruptedException e) {
        }
      }
      importantWork1();
    } finally {
      s.close();
    }
  }

  private void importantWork1() {
    TraceScope cur = Trace.startSpan("important work 1");
    try {
      Thread.sleep((long) (2000 * Math.random()));
      importantWork2();
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    } finally {
      cur.close();
    }
  }

  private void importantWork2() {
    TraceScope cur = Trace.startSpan("important work 2");
    try {
      Thread.sleep((long) (2000 * Math.random()));
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    } finally {
      cur.close();
    }
  }

  private class MyRunnable implements Runnable {
    @Override
    public void run() {
      try {
        Thread.sleep(750);
        Random r = ThreadLocalRandom.current();
        int importantNumber = 100 / r.nextInt(3);
        System.out.println("Important number: " + importantNumber);
      } catch (InterruptedException ie) {
        Thread.currentThread().interrupt();
      } catch (ArithmeticException ae) {
        TraceScope c = Trace.startSpan("dealing with arithmetic exception.");
        try {
          Thread.sleep((long) (3000 * Math.random()));
        } catch (InterruptedException ie1) {
          Thread.currentThread().interrupt();
        } finally {
          c.close();
        }
      }
    }
  }

  public void pretendRpcSend() {
    pretendRpcReceiveWithTraceInfo(Trace.currentSpan());
  }

  public void pretendRpcReceiveWithTraceInfo(Span parent) {
    TraceScope s = Trace.startSpan("received RPC", parent);
    try {
      importantWork1();
    } finally {
      s.close();
    }
  }
}
