/*
 * 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.hadoop.metrics2.lib;

import org.junit.Test;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static org.apache.hadoop.test.MockitoMaker.*;

import org.apache.hadoop.metrics2.MetricsCollector;
import org.apache.hadoop.metrics2.MetricsException;
import org.apache.hadoop.metrics2.MetricsRecordBuilder;
import org.apache.hadoop.metrics2.MetricsSource;
import org.apache.hadoop.metrics2.annotation.Metric;
import org.apache.hadoop.metrics2.annotation.Metric.*;
import org.apache.hadoop.metrics2.annotation.Metrics;
import org.apache.hadoop.metrics2.impl.MsInfo;
import static org.apache.hadoop.metrics2.lib.Interns.*;
import static org.apache.hadoop.test.MetricsAsserts.*;

public class TestMetricsAnnotations {

  static class MyMetrics {
    @Metric MutableCounterInt c1;
    @Metric({"Counter2", "Counter2 desc"}) MutableCounterLong c2;
    @Metric MutableGaugeInt g1, g2;
    @Metric("g3 desc") MutableGaugeLong g3;
    @Metric MutableRate r1;
    @Metric MutableStat s1;
    @Metric MutableRates rs1;
  }

  @Test public void testFields() {
    MyMetrics metrics = new MyMetrics();
    MetricsSource source = MetricsAnnotations.makeSource(metrics);

    metrics.c1.incr();
    metrics.c2.incr();
    metrics.g1.incr();
    metrics.g2.incr();
    metrics.g3.incr();
    metrics.r1.add(1);
    metrics.s1.add(1);
    metrics.rs1.add("rs1", 1);

    MetricsRecordBuilder rb = getMetrics(source);

    verify(rb).addCounter(info("C1", "C1"), 1);
    verify(rb).addCounter(info("Counter2", "Counter2 desc"), 1L);
    verify(rb).addGauge(info("G1", "G1"), 1);
    verify(rb).addGauge(info("G2", "G2"), 1);
    verify(rb).addGauge(info("G3", "g3 desc"), 1L);
    verify(rb).addCounter(info("R1NumOps", "Number of ops for r1"), 1L);
    verify(rb).addGauge(info("R1AvgTime", "Average time for r1"), 1.0);
    verify(rb).addCounter(info("S1NumOps", "Number of ops for s1"), 1L);
    verify(rb).addGauge(info("S1AvgTime", "Average time for s1"), 1.0);
    verify(rb).addCounter(info("Rs1NumOps", "Number of ops for rs1"), 1L);
    verify(rb).addGauge(info("Rs1AvgTime", "Average time for rs1"), 1.0);
  }

  static class BadMetrics {
    @Metric Integer i0;
  }

  @Test(expected=MetricsException.class) public void testBadFields() {
    MetricsAnnotations.makeSource(new BadMetrics());
  }

  static class MyMetrics2 {
    @Metric int getG1() { return 1; }
    @Metric long getG2() { return 2; }
    @Metric float getG3() { return 3; }
    @Metric double getG4() { return 4; }
    @Metric(type=Type.COUNTER) int getC1() { return 1; }
    @Metric(type=Type.COUNTER) long getC2() { return 2; }
    @Metric(type=Type.TAG) String getT1() { return "t1"; }
  }

  @Test public void testMethods() {
    MyMetrics2 metrics = new MyMetrics2();
    MetricsSource source = MetricsAnnotations.makeSource(metrics);
    MetricsRecordBuilder rb = getMetrics(source);

    verify(rb).addGauge(info("G1", "G1"), 1);
    verify(rb).addGauge(info("G2", "G2"), 2L);
    verify(rb).addGauge(info("G3", "G3"), 3.0f);
    verify(rb).addGauge(info("G4", "G4"), 4.0);
    verify(rb).addCounter(info("C1", "C1"), 1);
    verify(rb).addCounter(info("C2", "C2"), 2L);
    verify(rb).tag(info("T1", "T1"), "t1");
  }

  static class BadMetrics2 {
    @Metric int foo(int i) { return i; }
  }

  @Test(expected=IllegalArgumentException.class)
  public void testBadMethodWithArgs() {
    MetricsAnnotations.makeSource(new BadMetrics2());
  }

  static class BadMetrics3 {
    @Metric boolean foo() { return true; }
  }

  @Test(expected=MetricsException.class)
  public void testBadMethodReturnType() {
    MetricsAnnotations.makeSource(new BadMetrics3());
  }

  @Metrics(about="My metrics", context="foo")
  static class MyMetrics3 {
    @Metric int getG1() { return 1; }
  }

  @Test public void testClasses() {
    MetricsRecordBuilder rb = getMetrics(
        MetricsAnnotations.makeSource(new MyMetrics3()));
    MetricsCollector collector = rb.parent();

    verify(collector).addRecord(info("MyMetrics3", "My metrics"));
    verify(rb).add(tag(MsInfo.Context, "foo"));
  }

  static class HybridMetrics implements MetricsSource {
    final MetricsRegistry registry = new MetricsRegistry("HybridMetrics")
        .setContext("hybrid");
    @Metric("C0 desc") MutableCounterInt C0;

    @Metric int getG0() { return 0; }

    public void getMetrics(MetricsCollector collector, boolean all) {
      collector.addRecord("foo")
                  .setContext("foocontext")
                  .addCounter(info("C1", "C1 desc"), 1)
                  .endRecord()
               .addRecord("bar")
                  .setContext("barcontext")
                  .addGauge(info("G1", "G1 desc"), 1);
      registry.snapshot(collector.addRecord(registry.info()), all);
    }
  }

  @Test public void testHybrid() {
    HybridMetrics metrics = new HybridMetrics();
    MetricsSource source = MetricsAnnotations.makeSource(metrics);

    assertSame(metrics, source);
    metrics.C0.incr();
    MetricsRecordBuilder rb = getMetrics(source);
    MetricsCollector collector = rb.parent();

    verify(collector).addRecord("foo");
    verify(collector).addRecord("bar");
    verify(collector).addRecord(info("HybridMetrics", "HybridMetrics"));
    verify(rb).setContext("foocontext");
    verify(rb).addCounter(info("C1", "C1 desc"), 1);
    verify(rb).setContext("barcontext");
    verify(rb).addGauge(info("G1", "G1 desc"), 1);
    verify(rb).add(tag(MsInfo.Context, "hybrid"));
    verify(rb).addCounter(info("C0", "C0 desc"), 1);
    verify(rb).addGauge(info("G0", "G0"), 0);
  }

  @Metrics(context="hybrid")
  static class BadHybridMetrics implements MetricsSource {

    @Metric MutableCounterInt c1;

    public void getMetrics(MetricsCollector collector, boolean all) {
      collector.addRecord("foo");
    }
  }

  @Test(expected=MetricsException.class) public void testBadHybrid() {
    MetricsAnnotations.makeSource(new BadHybridMetrics());
  }

  static class EmptyMetrics {
    int foo;
  }

  @Test(expected=MetricsException.class) public void testEmptyMetrics() {
    MetricsAnnotations.makeSource(new EmptyMetrics());
  }
}
