// Copyright 2011 Google Inc. All Rights Reserved.
//
// Licensed 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 adaptorlib;

import static org.junit.Assert.*;

import org.junit.*;

import java.util.*;
import java.util.concurrent.atomic.*;
import java.util.logging.*;

/**
 * Test cases for {@link Dashboard}.
 */
public class DashboardTest {
  @Test
  public void testLogRpcMethod() {
    String golden = "Testing\n";

    Dashboard.CircularLogRpcMethod method
        = new Dashboard.CircularLogRpcMethod();
    try {
      Logger logger = Logger.getLogger("");
      Level origLevel = logger.getLevel();
      logger.setLevel(Level.FINEST);
      Logger.getLogger("").finest("Testing");
      logger.setLevel(origLevel);
      String str = (String) method.run(null);
      assertTrue(str.endsWith(golden));
    } finally {
      method.close();
    }
  }

  @Test
  public void testConfigRpcMethod() {
    Map<String, String> golden = new HashMap<String, String>();
    golden.put("gsa.characterEncoding", "UTF-8");
    golden.put("server.hostname", "localhost");

    MockConfig config = new MockConfig();
    config.setKey("gsa.characterEncoding", "UTF-8");
    config.setKey("server.hostname", "localhost");
    Dashboard.ConfigRpcMethod method = new Dashboard.ConfigRpcMethod(config);
    Map map = (Map) method.run(null);
    assertEquals(golden, map);
  }

  @Test
  public void testStatusRpcMethod() {
    List<Map<String, Object>> golden = new ArrayList<Map<String, Object>>();
    {
      Map<String, Object> goldenObj = new HashMap<String, Object>();
      goldenObj.put("source", "mock");
      goldenObj.put("code", "NORMAL");
      goldenObj.put("message", "fine");
      golden.add(goldenObj);
    }

    StatusMonitor monitor = new StatusMonitor();
    Status status = new Status(Status.Code.NORMAL, "fine");
    BasicStatusSource source = new BasicStatusSource("mock", status);
    monitor.addSource(source);
    Dashboard.StatusRpcMethod method = new Dashboard.StatusRpcMethod(monitor);
    List list = (List) method.run(null);
    assertEquals(golden, list);
  }

  @Test
  public void testLastPushStatusSource() {
    final MockTimeProvider timeProvider = new MockTimeProvider();
    final AtomicReference<Journal.CompletionStatus> ref
        = new AtomicReference<Journal.CompletionStatus>();
    final Journal journal = new Journal(timeProvider) {
      @Override
      public CompletionStatus getLastPushStatus() {
        return ref.get();
      }
    };
    StatusSource source = new Dashboard.LastPushStatusSource(journal);
    assertNotNull(source.getName());
    Status status;

    ref.set(Journal.CompletionStatus.SUCCESS);
    status = source.retrieveStatus();
    assertEquals(Status.Code.NORMAL, status.getCode());

    ref.set(Journal.CompletionStatus.INTERRUPTION);
    status = source.retrieveStatus();
    assertEquals(Status.Code.WARNING, status.getCode());

    ref.set(Journal.CompletionStatus.FAILURE);
    status = source.retrieveStatus();
    assertEquals(Status.Code.ERROR, status.getCode());
  }

  @Test
  public void testRetrieverStatusSource() {
    final MockTimeProvider timeProvider = new MockTimeProvider();
    final AtomicReference<Double> errorRate = new AtomicReference<Double>();
    final Journal journal = new Journal(timeProvider) {
      @Override
      public double getRetrieverErrorRate(long maxCount) {
        return errorRate.get();
      }
    };
    StatusSource source = new Dashboard.RetrieverStatusSource(journal);
    assertNotNull(source.getName());
    Status status;

    errorRate.set(0.);
    status = source.retrieveStatus();
    assertEquals(Status.Code.NORMAL, status.getCode());
    assertNotNull(status.getMessage());

    errorRate.set(Dashboard.RetrieverStatusSource.WARNING_THRESHOLD);
    status = source.retrieveStatus();
    assertEquals(Status.Code.WARNING, status.getCode());
    assertNotNull(status.getMessage());

    errorRate.set(Dashboard.RetrieverStatusSource.ERROR_THRESHOLD);
    status = source.retrieveStatus();
    assertEquals(Status.Code.ERROR, status.getCode());
    assertNotNull(status.getMessage());
  }

  @Test
  public void testGsaCrawlingStatusSource() {
    final MockTimeProvider timeProvider = new MockTimeProvider();
    final AtomicBoolean gsaCrawled = new AtomicBoolean();
    final Journal journal = new Journal(timeProvider) {
      @Override
      public boolean hasGsaCrawledWithinLastDay() {
        return gsaCrawled.get();
      }
    };
    StatusSource source = new Dashboard.GsaCrawlingStatusSource(journal);
    assertNotNull(source.getName());
    Status status;

    gsaCrawled.set(true);
    status = source.retrieveStatus();
    assertEquals(Status.Code.NORMAL, status.getCode());

    gsaCrawled.set(false);
    status = source.retrieveStatus();
    assertEquals(Status.Code.WARNING, status.getCode());
  }
}
