/*
 * Copyright (C) 2007 The Guava Authors
 *
 * Licensed 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 com.google.common.io;

import com.google.common.collect.Sets;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import junit.framework.TestCase;

/**
 * Base test case class for I/O tests.
 *
 * @author Chris Nokleberg
 * @author Colin Decker
 */
public abstract class IoTestCase extends TestCase {

  private static final Logger logger = Logger.getLogger(IoTestCase.class.getName());

  static final String I18N =
      "\u00CE\u00F1\u0163\u00E9\u0072\u00F1\u00E5\u0163\u00EE\u00F6"
          + "\u00F1\u00E5\u013C\u00EE\u017E\u00E5\u0163\u00EE\u00F6\u00F1";

  static final String ASCII =
      " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"
          + "[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";

  private File testDir;
  private File tempDir;

  private final Set<File> filesToDelete = Sets.newHashSet();

  @Override
  protected void tearDown() {
    for (File file : filesToDelete) {
      if (file.exists()) {
        delete(file);
      }
    }
    filesToDelete.clear();
  }

  private File getTestDir() throws IOException {
    if (testDir != null) {
      return testDir;
    }

    URL testFileUrl = IoTestCase.class.getResource("testdata/i18n.txt");
    if (testFileUrl == null) {
      throw new RuntimeException("unable to locate testdata directory");
    }

    if (testFileUrl.getProtocol().equals("file")) {
      try {
        File testFile = new File(testFileUrl.toURI());
        testDir = testFile.getParentFile(); // the testdata directory
      } catch (Exception ignore) {
        // probably URISyntaxException or IllegalArgumentException
        // fall back to copying URLs to files in the testDir == null block below
      }
    }

    if (testDir == null) {
      // testdata resources aren't file:// urls, so create a directory to store them in and then
      // copy the resources to the filesystem as needed
      testDir = createTempDir();
    }

    return testDir;
  }

  /** Returns the file with the given name under the testdata directory. */
  protected final File getTestFile(String name) throws IOException {
    File file = new File(getTestDir(), name);
    if (!file.exists()) {
      URL resourceUrl = IoTestCase.class.getResource("testdata/" + name);
      if (resourceUrl == null) {
        return null;
      }
      copy(resourceUrl, file);
    }

    return file;
  }

  /**
   * Creates a new temp dir for testing. The returned directory and all contents of it will be
   * deleted in the tear-down for this test.
   */
  protected final File createTempDir() throws IOException {
    File tempFile = File.createTempFile("IoTestCase", "");
    if (!tempFile.delete() || !tempFile.mkdir()) {
      throw new IOException("failed to create temp dir");
    }
    filesToDelete.add(tempFile);
    return tempFile;
  }

  /**
   * Gets a temp dir for testing. The returned directory and all contents of it will be deleted in
   * the tear-down for this test. Subsequent invocations of this method will return the same
   * directory.
   */
  protected final File getTempDir() throws IOException {
    if (tempDir == null) {
      tempDir = createTempDir();
    }

    return tempDir;
  }

  /**
   * Creates a new temp file in the temp directory returned by {@link #getTempDir()}. The file will
   * be deleted in the tear-down for this test.
   */
  protected final File createTempFile() throws IOException {
    return File.createTempFile("test", null, getTempDir());
  }

  /** Returns a byte array of length size that has values 0 .. size - 1. */
  static byte[] newPreFilledByteArray(int size) {
    return newPreFilledByteArray(0, size);
  }

  /** Returns a byte array of length size that has values offset .. offset + size - 1. */
  static byte[] newPreFilledByteArray(int offset, int size) {
    byte[] array = new byte[size];
    for (int i = 0; i < size; i++) {
      array[i] = (byte) (offset + i);
    }
    return array;
  }

  private static void copy(URL url, File file) throws IOException {
    InputStream in = url.openStream();
    try {
      OutputStream out = new FileOutputStream(file);
      try {
        byte[] buf = new byte[4096];
        for (int read = in.read(buf); read != -1; read = in.read(buf)) {
          out.write(buf, 0, read);
        }
      } finally {
        out.close();
      }
    } finally {
      in.close();
    }
  }

  @CanIgnoreReturnValue
  private boolean delete(File file) {
    if (file.isDirectory()) {
      File[] files = file.listFiles();
      if (files != null) {
        for (File f : files) {
          if (!delete(f)) {
            return false;
          }
        }
      }
    }

    if (!file.delete()) {
      logger.log(Level.WARNING, "couldn't delete file: {0}", new Object[] {file});
      return false;
    }

    return true;
  }
}
