/**
 * 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.tools.rumen;
import java.io.IOException;

import java.io.OutputStream;
import java.util.List;

import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;

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.junit.Ignore;
import org.junit.Test;
import static org.junit.Assert.*;
@Ignore
public class TestHistograms {

  /**
   * @throws IOException
   * 
   *           There should be files in the directory named by
   *           ${test.build.data}/rumen/histogram-test .
   * 
   *           There will be pairs of files, inputXxx.json and goldXxx.json .
   * 
   *           We read the input file as a HistogramRawTestData in json. Then we
   *           create a Histogram using the data field, and then a
   *           LoggedDiscreteCDF using the percentiles and scale field. Finally,
   *           we read the corresponding goldXxx.json as a LoggedDiscreteCDF and
   *           deepCompare them.
   */
  @Test
  public void testHistograms() throws IOException {
    final Configuration conf = new Configuration();
    final FileSystem lfs = FileSystem.getLocal(conf);
    final Path rootInputDir = lfs.makeQualified(new Path(
        System.getProperty("test.tools.input.dir", "target/input")));
    final Path rootInputFile = new Path(rootInputDir, "rumen/histogram-tests");


    FileStatus[] tests = lfs.listStatus(rootInputFile);

    for (int i = 0; i < tests.length; ++i) {
      Path filePath = tests[i].getPath();
      String fileName = filePath.getName();
      if (fileName.startsWith("input")) {
        String testName = fileName.substring("input".length());
        Path goldFilePath = new Path(rootInputFile, "gold"+testName);
        assertTrue("Gold file dies not exist", lfs.exists(goldFilePath));
        LoggedDiscreteCDF newResult = histogramFileToCDF(filePath, lfs);
        System.out.println("Testing a Histogram for " + fileName);
        FSDataInputStream goldStream = lfs.open(goldFilePath);
        JsonObjectMapperParser<LoggedDiscreteCDF> parser = new JsonObjectMapperParser<LoggedDiscreteCDF>(
            goldStream, LoggedDiscreteCDF.class); 
        try {
          LoggedDiscreteCDF dcdf = parser.getNext();
          dcdf.deepCompare(newResult, new TreePath(null, "<root>"));
        } catch (DeepInequalityException e) {
          fail(e.path.toString());
        }
        finally {
            parser.close();
        }
      }
    }
  }

  private static LoggedDiscreteCDF histogramFileToCDF(Path path, FileSystem fs)
      throws IOException {
    FSDataInputStream dataStream = fs.open(path);
    JsonObjectMapperParser<HistogramRawTestData> parser = new JsonObjectMapperParser<HistogramRawTestData>(
        dataStream, HistogramRawTestData.class);
    HistogramRawTestData data;
    try {
      data = parser.getNext();
    } finally {
      parser.close();
    }
    
    Histogram hist = new Histogram();
    List<Long> measurements = data.getData();
    List<Long> typeProbeData = new HistogramRawTestData().getData();

    assertTrue(
        "The data attribute of a jackson-reconstructed HistogramRawTestData "
            + " should be a " + typeProbeData.getClass().getName()
            + ", like a virgin HistogramRawTestData, but it's a "
            + measurements.getClass().getName(),
        measurements.getClass() == typeProbeData.getClass());

    for (int j = 0; j < measurements.size(); ++j) {
      hist.enter(measurements.get(j));
    }

    LoggedDiscreteCDF result = new LoggedDiscreteCDF();
    int[] percentiles = new int[data.getPercentiles().size()];

    for (int j = 0; j < data.getPercentiles().size(); ++j) {
      percentiles[j] = data.getPercentiles().get(j);
    }

    result.setCDF(hist, percentiles, data.getScale());
    return result;
  }
  
  public static void main(String[] args) throws IOException {
    final Configuration conf = new Configuration();
    final FileSystem lfs = FileSystem.getLocal(conf);

    for (String arg : args) {
      Path filePath = lfs.makeQualified(new Path(arg));
      String fileName = filePath.getName();
      if (fileName.startsWith("input")) {
        LoggedDiscreteCDF newResult = histogramFileToCDF(filePath, lfs);
        String testName = fileName.substring("input".length());
        Path goldFilePath = new Path(filePath.getParent(), "gold"+testName);

        ObjectMapper mapper = new ObjectMapper();
        JsonFactory factory = mapper.getFactory();
        FSDataOutputStream ostream = lfs.create(goldFilePath, true);
        JsonGenerator gen = factory.createGenerator((OutputStream)ostream,
            JsonEncoding.UTF8);
        gen.useDefaultPrettyPrinter();
        
        gen.writeObject(newResult);
        
        gen.close();
      } else {
        System.err.println("Input file not started with \"input\". File "+fileName+" skipped.");
      }
    }
  }
}
