/*
 * 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.tez.mapreduce.examples;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.util.ToolRunner;
import org.apache.hadoop.yarn.api.records.LocalResource;
import org.apache.hadoop.yarn.api.records.LocalResourceType;
import org.apache.hadoop.yarn.api.records.LocalResourceVisibility;
import org.apache.hadoop.yarn.util.ConverterUtils;
import org.apache.tez.client.TezClient;
import org.apache.tez.dag.api.DAG;
import org.apache.tez.dag.api.ProcessorDescriptor;
import org.apache.tez.dag.api.TezConfiguration;
import org.apache.tez.dag.api.TezException;
import org.apache.tez.dag.api.UserPayload;
import org.apache.tez.dag.api.Vertex;
import org.apache.tez.examples.TezExampleBase;
import org.apache.tez.runtime.api.ProcessorContext;
import org.apache.tez.runtime.library.processor.SimpleProcessor;
import org.apache.tez.util.StopWatch;

public class RPCLoadGen extends TezExampleBase {

  private static final Logger LOG = LoggerFactory.getLogger(RPCLoadGen.class);

  private static final String VIA_RPC = "viaRpc";
  private static final byte VIA_RPC_BYTE = (byte) 0x00;
  private static final String VIA_HDFS_DIST_CACHE = "viaHdfsDistCache";
  private static final byte VIA_HDFS_DIST_CACHE_BYTE = (byte) 0x01;
  private static final String VIA_HDFS_DIRECT_READ = "viaHdfsDirectRead";
  private static final byte VIA_HDFS_DIRECT_READ_BYTE = (byte) 0x02;
  private static final Random random = new Random();

  private static final String DISK_PAYLOAD_NAME = RPCLoadGen.class.getSimpleName() + "_payload";

  private FileSystem fs;
  private Path resourcePath;

  @Override
  protected final int runJob(String[] args, TezConfiguration tezConf, TezClient tezClient) throws
      TezException, InterruptedException, IOException {
    LOG.info("Running: " +
        this.getClass().getSimpleName());
    String mode = VIA_RPC;
    if (args.length == 4) {
      if (args[3].equals(VIA_RPC) || args[3].equals(VIA_HDFS_DIRECT_READ) ||
          args[3].equals(VIA_HDFS_DIST_CACHE)) {
        mode = args[3];
      } else {
        printUsage();
        return 2;
      }
    }

    int numTasks = Integer.parseInt(args[0]);
    int maxSleepTimeMillis = Integer.parseInt(args[1]);
    int payloadSizeBytes = Integer.parseInt(args[2]);
    LOG.info("Parameters: numTasks=" + numTasks + ", maxSleepTime(ms)=" + maxSleepTimeMillis +
        ", payloadSize(bytes)=" + payloadSizeBytes + ", mode=" + mode);

    DAG dag = createDAG(tezConf, numTasks, maxSleepTimeMillis, payloadSizeBytes, mode);
    try {
      return runDag(dag, false, LOG);
    } finally {
      if (fs != null) {
        if (resourcePath != null) {
          fs.delete(resourcePath, false);
        }
      }
    }
  }

  @Override
  protected void printUsage() {
    System.err.println(
        "Usage: " + "RPCLoadGen <numTasks> <max_sleep_time_millis> <get_task_payload_size> [" +
            "<" + VIA_RPC + ">|" + VIA_HDFS_DIST_CACHE + "|" + VIA_HDFS_DIRECT_READ + "]");
    ToolRunner.printGenericCommandUsage(System.err);
  }

  @Override
  protected final int validateArgs(String[] otherArgs) {
    return (otherArgs.length >=3 && otherArgs.length <=4) ? 0 : 2;
  }

  private DAG createDAG(TezConfiguration conf, int numTasks, int maxSleepTimeMillis,
                        int payloadSize, String mode) throws IOException {

    Map<String, LocalResource> localResourceMap = new HashMap<String, LocalResource>();
    UserPayload payload =
        createUserPayload(conf, maxSleepTimeMillis, payloadSize, mode, localResourceMap);

    Vertex vertex = Vertex.create("RPCLoadVertex",
        ProcessorDescriptor.create(RPCSleepProcessor.class.getName()).setUserPayload(
            payload), numTasks).addTaskLocalFiles(localResourceMap);

    return DAG.create("RPCLoadGen").addVertex(vertex);
  }

  private UserPayload createUserPayload(TezConfiguration conf, int maxSleepTimeMillis,
                                        int payloadSize, String mode,
                                        Map<String, LocalResource> localResources) throws
      IOException {
    ByteBuffer payload;
    if (mode.equals(VIA_RPC)) {
      if (payloadSize < 5) {
        payloadSize = 5; // To Configure the processor
      }
      byte[] payloadBytes = new byte[payloadSize];
      random.nextBytes(payloadBytes);
      payload = ByteBuffer.wrap(payloadBytes);
      payload.put(4, VIA_RPC_BYTE); // ViaRPC
    } else {
      // Actual payload
      byte[] payloadBytes = new byte[5];
      payload = ByteBuffer.wrap(payloadBytes);

      // Disk payload
      byte[] diskPayload = new byte[payloadSize];
      random.nextBytes(diskPayload);
      fs = FileSystem.get(conf);
      resourcePath = new Path(Path.SEPARATOR + "tmp", DISK_PAYLOAD_NAME);
      resourcePath = fs.makeQualified(resourcePath);
      FSDataOutputStream dataOut = fs.create(resourcePath, true);
      dataOut.write(diskPayload);
      dataOut.close();
      fs.setReplication(resourcePath, (short)10);
      FileStatus fileStatus = fs.getFileStatus(resourcePath);

      if (mode.equals(VIA_HDFS_DIST_CACHE)) {
        LocalResource lr = LocalResource.newInstance(ConverterUtils.getYarnUrlFromPath(resourcePath),
            LocalResourceType.ARCHIVE.FILE, LocalResourceVisibility.PRIVATE, fileStatus.getLen(),
            fileStatus.getModificationTime());
        localResources.put(DISK_PAYLOAD_NAME, lr);
        payload.put(4, VIA_HDFS_DIST_CACHE_BYTE); // ViaRPC
      } else if (mode.equals(VIA_HDFS_DIRECT_READ)) {
        payload.put(4, VIA_HDFS_DIRECT_READ_BYTE); // ViaRPC
      }
    }

    payload.putInt(0, maxSleepTimeMillis);
    return UserPayload.create(payload);
  }

  public static class RPCSleepProcessor extends SimpleProcessor {

    private final int sleepTimeMax;
    private final byte modeByte;

    public RPCSleepProcessor(ProcessorContext context) {
      super(context);
      sleepTimeMax = getContext().getUserPayload().getPayload().getInt(0);
      modeByte = getContext().getUserPayload().getPayload().get(4);
    }

    @Override
    public void run() throws Exception {
      StopWatch sw = new StopWatch().start();
      long sleepTime = random.nextInt(sleepTimeMax);
      if (modeByte == VIA_RPC_BYTE) {
        LOG.info("Received via RPC.");
      } else if (modeByte == VIA_HDFS_DIST_CACHE_BYTE) {
        LOG.info("Reading from local filesystem");
        FileSystem localFs = FileSystem.getLocal(new Configuration());
        FSDataInputStream is = localFs.open(new Path(DISK_PAYLOAD_NAME));
        IOUtils.toByteArray(is);
      } else if (modeByte == VIA_HDFS_DIRECT_READ_BYTE) {
        LOG.info("Reading from HDFS");
        FileSystem fs = FileSystem.get(new Configuration());
        FSDataInputStream is = fs.open(new Path(Path.SEPARATOR + "tmp", DISK_PAYLOAD_NAME));
        IOUtils.toByteArray(is);
      } else {
        throw new IllegalArgumentException("Unknown execution mode: [" + modeByte + "]");
      }
      LOG.info("TimeTakenToAccessPayload=" + sw.stop().now(TimeUnit.MILLISECONDS));
      LOG.info("Sleeping for: " + sleepTime);
      Thread.sleep(sleepTime);
    }
  }

  public static void main(String[] args) throws Exception {
    int res = ToolRunner.run(new Configuration(), new RPCLoadGen(), args);
    System.exit(res);
  }
}
