/*
 * 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
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * 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.ozone.genesis;

import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.hadoop.hdds.client.BlockID;
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.hdds.scm.container.common.helpers.StorageContainerException;
import org.apache.hadoop.ozone.OzoneConsts;
import org.apache.hadoop.ozone.common.ChunkBuffer;
import org.apache.hadoop.ozone.container.common.helpers.ChunkInfo;
import org.apache.hadoop.ozone.container.common.impl.ChunkLayOutVersion;
import org.apache.hadoop.ozone.container.common.transport.server.ratis.DispatcherContext;
import org.apache.hadoop.ozone.container.common.volume.HddsVolume;
import org.apache.hadoop.ozone.container.common.volume.ImmutableVolumeSet;
import org.apache.hadoop.ozone.container.common.volume.VolumeSet;
import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainer;
import org.apache.hadoop.ozone.container.keyvalue.KeyValueContainerData;
import org.apache.hadoop.ozone.container.keyvalue.impl.FilePerBlockStrategy;
import org.apache.hadoop.ozone.container.keyvalue.impl.FilePerChunkStrategy;
import org.apache.hadoop.ozone.container.keyvalue.interfaces.ChunkManager;

import static java.nio.charset.StandardCharsets.UTF_8;
import org.apache.commons.io.FileUtils;
import static org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric;
import static org.apache.hadoop.ozone.container.common.impl.ChunkLayOutVersion.FILE_PER_BLOCK;
import static org.apache.hadoop.ozone.container.common.impl.ChunkLayOutVersion.FILE_PER_CHUNK;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.TearDown;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;

/**
 * Benchmark for ChunkManager implementations.
 */
@Warmup(time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(time = 1, timeUnit = TimeUnit.SECONDS)
public class BenchmarkChunkManager {

  private static final String DEFAULT_TEST_DATA_DIR =
      "target" + File.separator + "test" + File.separator + "data";

  private static final AtomicLong CONTAINER_COUNTER = new AtomicLong();

  private static final DispatcherContext WRITE_STAGE =
      new DispatcherContext.Builder()
          .setStage(DispatcherContext.WriteChunkStage.WRITE_DATA)
          .build();

  private static final DispatcherContext COMMIT_STAGE =
      new DispatcherContext.Builder()
          .setStage(DispatcherContext.WriteChunkStage.COMMIT_DATA)
          .build();

  private static final long CONTAINER_SIZE = OzoneConsts.GB;
  private static final long BLOCK_SIZE = 256 * OzoneConsts.MB;

  private static final String SCM_ID = UUID.randomUUID().toString();
  private static final String DATANODE_ID = UUID.randomUUID().toString();

  /**
   * State for the benchmark.
   */
  @State(Scope.Benchmark)
  public static class BenchmarkState {

    @Param({"1048576", "4194304", "16777216", "67108864"})
    private int chunkSize;

    private File dir;
    private ChunkBuffer buffer;
    private VolumeSet volumeSet;
    private OzoneConfiguration config;

    private static File getTestDir() throws IOException {
      File dir = new File(DEFAULT_TEST_DATA_DIR).getAbsoluteFile();
      Files.createDirectories(dir.toPath());
      return dir;
    }

    @Setup(Level.Iteration)
    public void setup() throws IOException {
      dir = getTestDir();
      config = new OzoneConfiguration();
      HddsVolume volume = new HddsVolume.Builder(dir.getAbsolutePath())
          .conf(config)
          .datanodeUuid(DATANODE_ID)
          .build();

      volumeSet = new ImmutableVolumeSet(volume);

      byte[] arr = randomAlphanumeric(chunkSize).getBytes(UTF_8);
      buffer = ChunkBuffer.wrap(ByteBuffer.wrap(arr));
    }

    @TearDown(Level.Iteration)
    public void cleanup() {
      FileUtils.deleteQuietly(dir);
    }
  }

  @Benchmark
  public void writeMultipleFiles(BenchmarkState state, Blackhole sink)
      throws StorageContainerException {

    ChunkManager chunkManager = new FilePerChunkStrategy(true, null);
    benchmark(chunkManager, FILE_PER_CHUNK, state, sink);
  }

  @Benchmark
  public void writeSingleFile(BenchmarkState state, Blackhole sink)
      throws StorageContainerException {

    ChunkManager chunkManager = new FilePerBlockStrategy(true);
    benchmark(chunkManager, FILE_PER_BLOCK, state, sink);
  }

  private void benchmark(ChunkManager subject, ChunkLayOutVersion layout,
      BenchmarkState state, Blackhole sink)
      throws StorageContainerException {

    final long containerID = CONTAINER_COUNTER.getAndIncrement();

    KeyValueContainerData containerData =
        new KeyValueContainerData(containerID, layout,
            CONTAINER_SIZE, UUID.randomUUID().toString(),
            DATANODE_ID);
    KeyValueContainer container =
        new KeyValueContainer(containerData, state.config);
    container.create(state.volumeSet, (volumes, any) -> volumes.get(0), SCM_ID);

    final long blockCount = CONTAINER_SIZE / BLOCK_SIZE;
    final long chunkCount = BLOCK_SIZE / state.chunkSize;

    for (long b = 0; b < blockCount; b++) {
      final BlockID blockID = new BlockID(containerID, b);

      for (long c = 0; c < chunkCount; c++) {
        final String chunkName = String.format("block.%d.chunk.%d", b, c);
        final long offset = c * state.chunkSize;
        ChunkInfo chunkInfo = new ChunkInfo(chunkName, offset, state.chunkSize);
        ChunkBuffer data = state.buffer.duplicate(0, state.chunkSize);

        subject.writeChunk(container, blockID, chunkInfo, data, WRITE_STAGE);
        subject.writeChunk(container, blockID, chunkInfo, data, COMMIT_STAGE);

        sink.consume(chunkInfo);
      }
    }
  }

}
