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

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

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.client.RegionLocator;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.regionserver.HRegion;
import org.apache.hadoop.hbase.regionserver.HRegionServer;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.testclassification.MiscTests;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
import org.apache.hadoop.hbase.util.JVMClusterUtil;
import org.apache.hadoop.hbase.util.Threads;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.TestName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;

/**
 * Test HBASE-3694 whether the GlobalMemStoreSize is the same as the summary
 * of all the online region's MemStoreSize
 */
@Category({MiscTests.class, MediumTests.class})
public class TestGlobalMemStoreSize {

  @ClassRule
  public static final HBaseClassTestRule CLASS_RULE =
      HBaseClassTestRule.forClass(TestGlobalMemStoreSize.class);

  private static final Logger LOG = LoggerFactory.getLogger(TestGlobalMemStoreSize.class);
  private static int regionServerNum = 4;
  private static int regionNum = 16;
  // total region num = region num + meta regions
  private static int totalRegionNum = regionNum + 1;

  private HBaseTestingUtil TEST_UTIL;
  private SingleProcessHBaseCluster cluster;

  @Rule
  public TestName name = new TestName();

  /**
   * Test the global mem store size in the region server is equal to sum of each
   * region's mem store size
   * @throws Exception
   */
  @Test
  public void testGlobalMemStore() throws Exception {
    // Start the cluster
    LOG.info("Starting cluster");
    Configuration conf = HBaseConfiguration.create();
    TEST_UTIL = new HBaseTestingUtil(conf);
    TEST_UTIL.startMiniCluster(regionServerNum);
    cluster = TEST_UTIL.getHBaseCluster();
    LOG.info("Waiting for active/ready master");
    cluster.waitForActiveAndReadyMaster();

    // Create a table with regions
    final TableName table = TableName.valueOf(name.getMethodName());
    byte [] family = Bytes.toBytes("family");
    LOG.info("Creating table with " + regionNum + " regions");
    Table ht = TEST_UTIL.createMultiRegionTable(table, family, regionNum);
    int numRegions = -1;
    try (RegionLocator r = TEST_UTIL.getConnection().getRegionLocator(table)) {
      numRegions = r.getStartKeys().length;
    }
    assertEquals(regionNum,numRegions);
    waitForAllRegionsAssigned();

    for (HRegionServer server : getOnlineRegionServers()) {
      long globalMemStoreSize = 0;
      for (RegionInfo regionInfo :
          ProtobufUtil.getOnlineRegions(null, server.getRSRpcServices())) {
        globalMemStoreSize += server.getRegion(regionInfo.getEncodedName()).getMemStoreDataSize();
      }
      assertEquals(server.getRegionServerAccounting().getGlobalMemStoreDataSize(),
        globalMemStoreSize);
    }

    // check the global memstore size after flush
    int i = 0;
    for (HRegionServer server : getOnlineRegionServers()) {
      LOG.info("Starting flushes on " + server.getServerName() +
        ", size=" + server.getRegionServerAccounting().getGlobalMemStoreDataSize());

      for (RegionInfo regionInfo :
          ProtobufUtil.getOnlineRegions(null, server.getRSRpcServices())) {
        HRegion r = server.getRegion(regionInfo.getEncodedName());
        flush(r, server);
      }
      LOG.info("Post flush on " + server.getServerName());
      long now = EnvironmentEdgeManager.currentTime();
      long timeout = now + 1000;
      while(server.getRegionServerAccounting().getGlobalMemStoreDataSize() != 0 &&
          timeout < EnvironmentEdgeManager.currentTime()) {
        Threads.sleep(10);
      }
      long size = server.getRegionServerAccounting().getGlobalMemStoreDataSize();
      if (size > 0) {
        // If size > 0, see if its because the meta region got edits while
        // our test was running....
        for (RegionInfo regionInfo :
            ProtobufUtil.getOnlineRegions(null, server.getRSRpcServices())) {
          HRegion r = server.getRegion(regionInfo.getEncodedName());
          long l = r.getMemStoreDataSize();
          if (l > 0) {
            // Only meta could have edits at this stage.  Give it another flush
            // clear them.
            assertTrue(regionInfo.isMetaRegion());
            LOG.info(r.toString() + " " + l + ", reflushing");
            r.flush(true);
          }
        }
      }
      size = server.getRegionServerAccounting().getGlobalMemStoreDataSize();
      assertEquals("Server=" + server.getServerName() + ", i=" + i++, 0, size);
    }

    ht.close();
    TEST_UTIL.shutdownMiniCluster();
  }

  /**
   * Flush and log stats on flush
   * @param r
   * @param server
   * @throws IOException
   */
  private void flush(final HRegion r, final HRegionServer server)
  throws IOException {
    LOG.info("Flush " + r.toString() + " on " + server.getServerName() +
      ", " +  r.flush(true) + ", size=" +
      server.getRegionServerAccounting().getGlobalMemStoreDataSize());
  }

  private List<HRegionServer> getOnlineRegionServers() {
    List<HRegionServer> list = new ArrayList<>();
    for (JVMClusterUtil.RegionServerThread rst :
          cluster.getRegionServerThreads()) {
      if (rst.getRegionServer().isOnline()) {
        list.add(rst.getRegionServer());
      }
    }
    return list;
  }

  /**
   * Wait until all the regions are assigned.
   */
  private void waitForAllRegionsAssigned() throws IOException {
    while (true) {
      int regionCount = HBaseTestingUtil.getAllOnlineRegions(cluster).size();
      if (regionCount >= totalRegionNum) break;
      LOG.debug("Waiting for there to be "+ totalRegionNum
        +" regions, but there are " + regionCount + " right now.");
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {}
    }
  }
}
