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

import java.io.*;
import java.security.PrivilegedExceptionAction;

import junit.framework.TestCase;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.io.DataOutputBuffer;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.mapred.lib.IdentityMapper;
import org.apache.hadoop.mapred.lib.IdentityReducer;
import org.apache.hadoop.mapreduce.JobSubmissionFiles;
import org.apache.hadoop.mapreduce.protocol.ClientProtocol;
import org.apache.hadoop.mapreduce.split.JobSplitWriter;
import org.apache.hadoop.mapreduce.split.JobSplit.SplitMetaInfo;
import org.apache.hadoop.security.*;

/**
 * A JUnit test to test Mini Map-Reduce Cluster with Mini-DFS.
 */
public class TestMiniMRWithDFSWithDistinctUsers extends TestCase {
  static final UserGroupInformation DFS_UGI = createUGI("dfs", true); 
  static final UserGroupInformation PI_UGI = createUGI("pi", false); 
  static final UserGroupInformation WC_UGI = createUGI("wc", false); 

  static UserGroupInformation createUGI(String name, boolean issuper) {
    String group = issuper? "supergroup": name;
    
    return UserGroupInformation.createUserForTesting(name, new String[]{group});
  }
  
  static void mkdir(FileSystem fs, String dir) throws IOException {
    Path p = new Path(dir);
    fs.mkdirs(p);
    fs.setPermission(p, new FsPermission((short)0777));
  }

  // runs a sample job as a user (ugi)
  RunningJob runJobAsUser(final JobConf job, UserGroupInformation ugi) 
  throws Exception {
    ClientProtocol jobSubmitClient = 
      TestSubmitJob.getJobSubmitClient(job, ugi);
    org.apache.hadoop.mapreduce.JobID id = jobSubmitClient.getNewJobID();
    
    InputSplit[] splits = computeJobSplit(JobID.downgrade(id), job);
    final Path jobSubmitDir = new Path(id.toString());
    FileSystem fs = ugi.doAs(new PrivilegedExceptionAction<FileSystem>() {
      public FileSystem run() throws IOException {
        return jobSubmitDir.getFileSystem(job);
      }
    });
    Path qJobSubmitDir = jobSubmitDir.makeQualified(fs);
    uploadJobFiles(JobID.downgrade(id), splits, qJobSubmitDir, ugi, job);
    
    jobSubmitClient.submitJob(id, qJobSubmitDir.toString(), null);
    
    JobClient jc = new JobClient(job);
    return jc.getJob(JobID.downgrade(id));
  }
  
  // a helper api for split computation
  private InputSplit[] computeJobSplit(JobID id, JobConf conf) 
  throws IOException {
    InputSplit[] splits = 
      conf.getInputFormat().getSplits(conf, conf.getNumMapTasks());
    conf.setNumMapTasks(splits.length);
    return splits;
  }


  // a helper api for split submission
  private void uploadJobFiles(JobID id, InputSplit[] splits,
                             Path jobSubmitDir, UserGroupInformation ugi, 
                             final JobConf conf) 
  throws Exception {
    final Path confLocation = JobSubmissionFiles.getJobConfPath(jobSubmitDir);
    FileSystem fs = ugi.doAs(new PrivilegedExceptionAction<FileSystem>() {
      public FileSystem run() throws IOException {
        return confLocation.getFileSystem(conf);
      }
    });
    JobSplitWriter.createSplitFiles(jobSubmitDir, conf, fs, splits);
    FsPermission perm = new FsPermission((short)0700);
    
    // localize conf
    DataOutputStream confOut = FileSystem.create(fs, confLocation, perm);
    conf.writeXml(confOut);
    confOut.close();
  }
  
  public void testDistinctUsers() throws Exception {
    MiniMRCluster mr = null;
    Configuration conf = new Configuration();
    final MiniDFSCluster dfs = new MiniDFSCluster(conf, 4, true, null);
    try {
          
      FileSystem fs = DFS_UGI.doAs(new PrivilegedExceptionAction<FileSystem>() {
        public FileSystem run() throws IOException {
          return dfs.getFileSystem();
        }
      });
      mkdir(fs, "/user");
      mkdir(fs, "/mapred");

      UserGroupInformation MR_UGI = UserGroupInformation.getLoginUser(); 
      mr = new MiniMRCluster(0, 0, 4, dfs.getFileSystem().getUri().toString(),
           1, null, null, MR_UGI);
      String jobTrackerName = "localhost:" + mr.getJobTrackerPort();

      JobConf job1 = mr.createJobConf();
      String input = "The quick brown fox\nhas many silly\n" 
                     + "red fox sox\n";
      Path inDir = new Path("/testing/distinct/input");
      Path outDir = new Path("/testing/distinct/output");
      TestMiniMRClasspath.configureWordCount(fs, jobTrackerName, job1, 
                                             input, 2, 1, inDir, outDir);
      runJobAsUser(job1, PI_UGI);

      JobConf job2 = mr.createJobConf();
      Path inDir2 = new Path("/testing/distinct/input2");
      Path outDir2 = new Path("/testing/distinct/output2");
      TestMiniMRClasspath.configureWordCount(fs, jobTrackerName, job2, 
                                             input, 2, 1, inDir2, outDir2);
      runJobAsUser(job2, WC_UGI);
    } finally {
      if (dfs != null) { dfs.shutdown(); }
      if (mr != null) { mr.shutdown();}
    }
  }
  
  public void testRestartWithDistinctUsers() {
    
  }
}
