package org.apache.lucene.util;

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.lucene.util.LuceneTestCase.SuppressSysoutChecks;

import com.carrotsearch.randomizedtesting.RandomizedTest;
import com.carrotsearch.randomizedtesting.rules.TestRuleAdapter;


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

/**
 * Fails the suite if it prints over the given limit of bytes to either
 * {@link System#out} or {@link System#err},
 * unless the condition is not enforced (see {@link #isEnforced()}).
 */
public class TestRuleLimitSysouts extends TestRuleAdapter {
  /**
   * Max limit of bytes printed to either {@link System#out} or {@link System#err}. 
   * This limit is enforced per-class (suite).
   */
  public final static int DEFAULT_SYSOUT_BYTES_THRESHOLD = 8 * 1024;

  /**
   * An annotation specifying the limit of bytes per class.
   */
  @Documented
  @Inherited
  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.TYPE)
  public static @interface Limit {
    public int bytes();
  }

  private final static AtomicInteger bytesWritten = new AtomicInteger();

  private final static DelegateStream capturedSystemOut;
  private final static DelegateStream capturedSystemErr;
  
  /**
   * We capture system output and error streams as early as possible because
   * certain components (like the Java logging system) steal these references and
   * never refresh them.
   * 
   * Also, for this exact reason, we cannot change delegate streams for every suite.
   * This isn't as elegant as it should be, but there's no workaround for this.
   */
  static {
    System.out.flush();
    System.err.flush();

    final String csn = Charset.defaultCharset().name();
    capturedSystemOut = new DelegateStream(System.out, csn, bytesWritten);
    capturedSystemErr = new DelegateStream(System.err, csn, bytesWritten);

    System.setOut(capturedSystemOut.printStream);
    System.setErr(capturedSystemErr.printStream);
  }

  /**
   * Test failures from any tests or rules before.
   */
  private final TestRuleMarkFailure failureMarker;

  /**
   * Tracks the number of bytes written to an underlying stream by
   * incrementing an {@link AtomicInteger}.
   */
  static class DelegateStream extends FilterOutputStream {
    final PrintStream printStream;
    final AtomicInteger bytesCounter;

    public DelegateStream(OutputStream delegate, String charset, AtomicInteger bytesCounter) {
      super(delegate);
      try {
        this.printStream = new PrintStream(this, true, charset);
        this.bytesCounter = bytesCounter;
      } catch (UnsupportedEncodingException e) {
        throw new RuntimeException(e);
      }
    }

    // Do override all three write() methods to make sure nothing slips through.

    @Override
    public void write(byte[] b) throws IOException {
      if (b.length > 0) {
        bytesCounter.addAndGet(b.length);
      }
      super.write(b);
    }
    
    @Override
    public void write(byte[] b, int off, int len) throws IOException {
      if (len > 0) {
        bytesCounter.addAndGet(len);
      }
      super.write(b, off, len);
    }

    @Override
    public void write(int b) throws IOException {
      bytesCounter.incrementAndGet();
      super.write(b);
    }
  }

  public TestRuleLimitSysouts(TestRuleMarkFailure failureMarker) {
    this.failureMarker = failureMarker;
  }

  
  /** */
  @Override
  protected void before() throws Throwable {
    if (isEnforced()) {
      checkCaptureStreams();
    }
    resetCaptureState();
    validateClassAnnotations();
  }

  private void validateClassAnnotations() {
    Class<?> target = RandomizedTest.getContext().getTargetClass();
    if (target.isAnnotationPresent(Limit.class)) {
      int bytes = target.getAnnotation(Limit.class).bytes();
      if (bytes < 0 || bytes > 1 * 1024 * 1024) {
        throw new AssertionError("The sysout limit is insane. Did you want to use "
            + "@" + LuceneTestCase.SuppressSysoutChecks.class.getName() + " annotation to "
            + "avoid sysout checks entirely?");
      }
    }
  }

  /**
   * Ensures {@link System#out} and {@link System#err} point to delegate streams.
   */
  public static void checkCaptureStreams() {
    // Make sure we still hold the right references to wrapper streams.
    if (System.out != capturedSystemOut.printStream) {
      throw new AssertionError("Something has changed System.out to: " + System.out.getClass().getName());
    }
    if (System.err != capturedSystemErr.printStream) {
      throw new AssertionError("Something has changed System.err to: " + System.err.getClass().getName());
    }
  }

  protected boolean isEnforced() {
    Class<?> target = RandomizedTest.getContext().getTargetClass();

    if (LuceneTestCase.VERBOSE || 
        LuceneTestCase.INFOSTREAM ||
        target.isAnnotationPresent(SuppressSysoutChecks.class)) {
      return false;
    }
    
    if (!target.isAnnotationPresent(Limit.class)) {
      return false;
    }

    return true;
  }

  /**
   * We're only interested in failing the suite if it was successful (otherwise
   * just propagate the original problem and don't bother doing anything else).
   */
  @Override
  protected void afterIfSuccessful() throws Throwable {
    if (isEnforced()) {
      checkCaptureStreams();
  
      // Flush any buffers.
      capturedSystemOut.printStream.flush();
      capturedSystemErr.printStream.flush();
  
      // Check for offenders, but only if everything was successful so far.
      int limit = RandomizedTest.getContext().getTargetClass().getAnnotation(Limit.class).bytes();
      if (bytesWritten.get() >= limit && failureMarker.wasSuccessful()) {
        throw new AssertionError(String.format(Locale.ENGLISH, 
            "The test or suite printed %d bytes to stdout and stderr," +
            " even though the limit was set to %d bytes. Increase the limit with @%s, ignore it completely" +
            " with @%s or run with -Dtests.verbose=true",
            bytesWritten.get(),
            limit,
            Limit.class.getSimpleName(),
            SuppressSysoutChecks.class.getSimpleName()));
      }
    }
  }

  @Override
  protected void afterAlways(List<Throwable> errors) throws Throwable {
    resetCaptureState();
  }

  private void resetCaptureState() {
    capturedSystemOut.printStream.flush();
    capturedSystemErr.printStream.flush();
    bytesWritten.set(0);
  }
}

