/**
 * 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.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 HBaseTestingUtility TEST_UTIL;
  private MiniHBaseCluster 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 HBaseTestingUtility(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 = System.currentTimeMillis();
      long timeout = now + 1000;
      while(server.getRegionServerAccounting().getGlobalMemStoreDataSize() != 0 &&
          timeout < System.currentTimeMillis()) {
        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 = HBaseTestingUtility.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) {}
    }
  }
}
