/*
 * 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.UnableToCompleteException;
import com.google.gwt.dev.json.JsonArray;
import com.google.gwt.dev.json.JsonObject;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Contains everything that the code server knows about a GWT app (module), including how
 * to recompile it and where the compiler output is.
 */
class ModuleState {
  private final AtomicReference<CompileDir> current = new AtomicReference<CompileDir>();
  private final Recompiler recompiler;
  private final TreeLogger logger;

  ModuleState(Recompiler recompiler, TreeLogger logger, boolean noPrecompile)
      throws UnableToCompleteException {
    this.recompiler = recompiler;
    this.logger = logger;

    CompileDir compileDir;
    if (noPrecompile) {
      compileDir = recompiler.noCompile();
    } else {
      Map<String, String> defaultProps = new HashMap<String, String>();
      defaultProps.put("user.agent", "safari");
      defaultProps.put("locale", "en");
      defaultProps.put("compiler.useSourceMaps", "true");
      compileDir = recompiler.compile(defaultProps);
    }
    current.set(compileDir);
  }

  /**
   * Recompiles the module with the given binding properties. If successful, this changes the
   * location of the output directory. (The log file changes both on success and on failure.
   *
   * @param bindingProperties The properties used to compile. (Chooses the permutation.)
   * @return true if the compile finished successfully.
   */
  boolean recompile(Map<String, String> bindingProperties) {
    try {
      current.set(recompiler.compile(bindingProperties));
      return true;
    } catch (UnableToCompleteException e) {
      logger.log(TreeLogger.Type.WARN, "continuing to serve previous version");
      return false;
    }
  }

  /**
   * Returns the name of this module (after renaming).
   */
  String getModuleName() {
    return recompiler.getModuleName();
  }

  /**
   * Returns the source map file from the most recent recompile.
   * @throws RuntimeException if unable
   */
  File findSourceMap() {
    String moduleName = recompiler.getModuleName();
    File symbolMapsDir = current.get().findSymbolMapDir(moduleName);
    if (symbolMapsDir == null) {
      throw new RuntimeException("Can't find symbolMaps dir for " + moduleName);
    }

    File[] sourceMapFiles = symbolMapsDir.listFiles(new FilenameFilter() {
      @Override
      public boolean accept(File dir, String name) {
        return name.matches(".*_sourceMap0.json");
      }
    });

    if (sourceMapFiles == null) {
      throw new RuntimeException("Can't list contents of symbolMaps dir: " + symbolMapsDir);
    }

    if (sourceMapFiles.length > 1) {
      throw new RuntimeException("Multiple fragment 0 sourcemaps found. Too many permutations.");
    }

    if (sourceMapFiles.length == 0) {
      throw new RuntimeException("No sourcemaps found. Not enabled?");
    }

    return new File(symbolMapsDir, sourceMapFiles[0].getName());
  }

  /**
   * Finds a source file (or other resource) that's either in this module's source path, or
   * is a generated file.
   * @param path location of the file relative to its directory in the classpath, or (if
   *   it starts with "gen/"), a generated file.
   * @return bytes in the file, or null if there's no such source file.
   */
  InputStream openSourceFile(String path) throws IOException {

    if (path.startsWith("gen/")) {
      // generated file?
      String rest = path.substring("gen/".length());
      File fileInGenDir = new File(getGenDir(), rest);
      if (!fileInGenDir.isFile()) {
        return null;
      }
      return new BufferedInputStream(new FileInputStream(fileInGenDir));
    } else {
      // regular source file?
      URL resource = recompiler.getResourceLoader().getResource(path);
      if (resource == null) {
        return null;
      }
      return resource.openStream();
    }
  }

  /**
   * Returns the location of a file in the compiler's output directory from the
   * last time this module was recompiled. The location will change after a successful
   * recompile.
   * @param urlPath The path to the file. This should be a relative path beginning
   * with the module name (after renaming).
   * @return The location of the file, which might not actually exist.
   */
  File getOutputFile(String urlPath) {
    return new File(current.get().getWarDir(), urlPath);
  }

  /**
   * Returns the log file from the last time this module was recompiled. This changes
   * after every call to {@link #recompile}.
   */
  File getCompileLog() {
    return recompiler.getLastLog();
  }

  File getGenDir() {
    return current.get().getGenDir();
  }

  File getWarDir() {
    return current.get().getWarDir();
  }

  JsonObject getTemplateVariables() {
    JsonObject result = new JsonObject();
    result.put("moduleName", getModuleName());
    result.put("files", listModuleFiles());
    return result;
  }

  private JsonArray listModuleFiles() {
    File[] files = new File(getWarDir(), getModuleName()).listFiles();
    if (files == null) {
      return new JsonArray();
    }
    Arrays.sort(files);

    JsonArray result = new JsonArray();
    for (File file : files) {
      if (file.isFile()) {
        JsonObject map = new JsonObject();
        map.put("name", file.getName());
        map.put("link", file.getName());
        result.add(map);
      }
    }
    return result;
  }
}
