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

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.tools.rumen.JobStory;
import org.apache.hadoop.tools.rumen.JobStoryProducer;
import org.apache.hadoop.mapred.gridmix.Statistics.JobStats;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Condition;

public class SerialJobFactory extends JobFactory<JobStats> {

  public static final Log LOG = LogFactory.getLog(SerialJobFactory.class);
  private final Condition jobCompleted = lock.newCondition();

  /**
   * Creating a new instance does not start the thread.
   *
   * @param submitter   Component to which deserialized jobs are passed
   * @param jobProducer Job story producer
   *                    {@link org.apache.hadoop.tools.rumen.ZombieJobProducer}
   * @param scratch     Directory into which to write output from simulated jobs
   * @param conf        Config passed to all jobs to be submitted
   * @param startFlag   Latch released from main to start pipeline
   * @throws java.io.IOException
   */
  public SerialJobFactory(
    JobSubmitter submitter, JobStoryProducer jobProducer, Path scratch,
    Configuration conf, CountDownLatch startFlag, UserResolver resolver)
    throws IOException {
    super(submitter, jobProducer, scratch, conf, startFlag, resolver);
  }

  @Override
  public Thread createReaderThread() {
    return new SerialReaderThread("SerialJobFactory");
  }

  private class SerialReaderThread extends Thread {

    public SerialReaderThread(String threadName) {
      super(threadName);
    }

    /**
     * SERIAL : In this scenario .  method waits on notification ,
     * that a submitted job is actually completed. Logic is simple.
     * ===
     * while(true) {
     * wait till previousjob is completed.
     * break;
     * }
     * submit newJob.
     * previousJob = newJob;
     * ==
     */
    @Override
    public void run() {
      try {
        startFlag.await();
        if (Thread.currentThread().isInterrupted()) {
          return;
        }
        LOG.info("START SERIAL @ " + System.currentTimeMillis());
        GridmixJob prevJob;
        while (!Thread.currentThread().isInterrupted()) {
          final JobStory job;
          try {
            job = getNextJobFiltered();
            if (null == job) {
              return;
            }
            if (LOG.isDebugEnabled()) {
              LOG.debug(
                "Serial mode submitting job " + job.getName());
            }
            prevJob = jobCreator.createGridmixJob(
              conf, 0L, job, scratch, 
              userResolver.getTargetUgi(
                UserGroupInformation.createRemoteUser(job.getUser())),
              sequence.getAndIncrement());

            lock.lock();
            try {
              LOG.info(" Submitted the job " + prevJob);
              submitter.add(prevJob);
            } finally {
              lock.unlock();
            }
          } catch (IOException e) {
            error = e;
            //If submission of current job fails , try to submit the next job.
            return;
          }

          if (prevJob != null) {
            //Wait till previous job submitted is completed.
            lock.lock();
            try {
              while (true) {
                try {
                  jobCompleted.await();
                } catch (InterruptedException ie) {
                  LOG.error(
                    " Error in SerialJobFactory while waiting for job completion ",
                    ie);
                  return;
                }
                if (LOG.isDebugEnabled()) {
                  LOG.info(" job " + job.getName() + " completed ");
                }
                break;
              }
            } finally {
              lock.unlock();
            }
            prevJob = null;
          }
        }
      } catch (InterruptedException e) {
        return;
      } finally {
        IOUtils.cleanup(null, jobProducer);
      }
    }

  }

  /**
   * SERIAL. Once you get notification from StatsCollector about the job
   * completion ,simply notify the waiting thread.
   *
   * @param item
   */
  @Override
  public void update(Statistics.JobStats item) {
    //simply notify in case of serial submissions. We are just bothered
    //if submitted job is completed or not.
    lock.lock();
    try {
      jobCompleted.signalAll();
    } finally {
      lock.unlock();
    }
  }

  /**
   * Start the reader thread, wait for latch if necessary.
   */
  @Override
  public void start() {
    LOG.info(" Starting Serial submission ");
    this.rThread.start();
  }
}
