/*
 * Copyright 2011 Google Inc.
 *
 * 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.gwt.dev.codeserver;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.TreeLogger.Type;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.util.Util;

import java.io.File;
import java.io.IOException;

/**
 * The directory tree where Super Dev Mode keeps all the files for one GWT app.
 * Each time we recompile the app, we create a new subdirectory (see {@link CompileDir}).
 * In addition, there are some files that are shared between recompiles, such as
 * the unit cache.
 */
class OutboxDir {
  private static final String COMPILE_DIR_PREFIX = "compile-";
  private static final int MAX_CREATE_DIRECTORY_RETRIES = 50;

  private final File root;
  private int nextCompileId = 1;

  /**
   * @see #create
   */
  private OutboxDir(File root) {
    this.root = root;
  }

  File getSpeedTracerLogFile() {
    return new File(root, "speedtracer.html");
  }

  File getUnitCacheDir() {
    return new File(root, "gwt-unitcache");
  }

  /**
   * Creates a fresh, empty compile directory.
   */
  CompileDir makeCompileDir(TreeLogger logger)
      throws UnableToCompleteException {

    for (int i = 0; i < MAX_CREATE_DIRECTORY_RETRIES; i++) {
      int candidateId = nextCompileId++;
      File candidate = new File(root, COMPILE_DIR_PREFIX + candidateId);
      try {
        return CompileDir.create(candidate, logger);
      } catch (UnableToCompleteException e) {
        // try again
      }
    }

    logger.log(Type.ERROR, "Gave up trying to create a compile directory.");
    throw new UnableToCompleteException();
  }

  /**
   * Creates an outbox directory, doing any cleanup needed.
   * @param dir the directory to use. It need not exist, but
   * the parent dir should exist.
   */
  static OutboxDir create(File dir, TreeLogger logger) throws IOException {
    if (!dir.isDirectory() && !dir.mkdir()) {
      throw new IOException("can't create app directory: " + dir);
    }

    File[] children = dir.listFiles();
    if (children == null) {
      throw new IOException("unable to list files in " + dir);
    }

    // Try to clean up existing subdirectories.
    // (This is not guaranteed to delete all directories on Windows if a directory is locked.)
    for (File candidate : children) {
      if (candidate.getName().startsWith(COMPILE_DIR_PREFIX)) {
        Util.recursiveDelete(candidate, false);
        if (candidate.exists()) {
          logger.log(Type.WARN, "unable to delete '" + candidate + "' (skipped)");
        }
      }
    }

    return new OutboxDir(dir);
  }
}
