/*
 * Copyright 2008 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;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.jjs.PermutationResult;
import com.google.gwt.dev.jjs.UnifiedAst;
import com.google.gwt.dev.util.PersistenceBackedObject;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * Create a single in-process PermutationWorker. This WorkerFactory is intended
 * to be used as a fall-back in case the other PermutationWorkers are unable to
 * complete.
 */
public class ThreadedPermutationWorkerFactory extends PermutationWorkerFactory {

  private static class ThreadedPermutationWorker implements PermutationWorker {
    private final UnifiedAst ast;
    private final int id;

    public ThreadedPermutationWorker(UnifiedAst ast, int id) {
      this.ast = ast;
      this.id = id;
    }

    @Override
    public void compile(TreeLogger logger, CompilerContext compilerContext, Permutation permutation,
        PersistenceBackedObject<PermutationResult> resultFile)
        throws TransientWorkerException, UnableToCompleteException {
      try {
        PermutationResult result = CompilePerms.compile(logger, compilerContext, permutation, ast);
        resultFile.set(logger, result);
      } catch (OutOfMemoryError e) {
        logger.log(TreeLogger.ERROR,
            "OutOfMemoryError: Increase heap size or lower "
                + MAX_THREADS_PROPERTY, e);
        throw new UnableToCompleteException();
      } catch (StackOverflowError e) {
        logger.log(TreeLogger.ERROR, "StackOverflowError: Increase stack size",
            e);
        throw new UnableToCompleteException();
      }
    }

    @Override
    public String getName() {
      return "In-process PermutationWorker " + id;
    }

    @Override
    public void shutdown() {
      // No-op
    }
  }

  /**
   * A Java system property that can be used to change the number of in-process
   * threads used.
   */
  public static final String MAX_THREADS_PROPERTY = "gwt.jjs.maxThreads";

  @Override
  public Collection<PermutationWorker> getWorkers(TreeLogger logger,
      UnifiedAst unifiedAst, int numWorkers) throws UnableToCompleteException {
    logger.log(TreeLogger.SPAM, "Creating ThreadedPermutationWorkers");

    numWorkers = Math.min(numWorkers, Integer.getInteger(MAX_THREADS_PROPERTY,
        1));

    if (numWorkers == 0) {
      return Collections.emptyList();
    }

    // The worker will deserialize a new copy
    List<PermutationWorker> toReturn = new ArrayList<PermutationWorker>(
        numWorkers);
    for (int i = 0; i < numWorkers; i++) {
      toReturn.add(new ThreadedPermutationWorker(unifiedAst, i));
    }
    return toReturn;
  }

  @Override
  public boolean isLocal() {
    return true;
  }
}
