/*
 * Copyright 2012-present Facebook, 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.facebook.buck.cli;

import com.google.common.base.Optional;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableSet;

import org.kohsuke.args4j.Option;

import java.util.Set;

import javax.annotation.Nullable;

public class TestCommandOptions extends BuildCommandOptions {

  @Option(name = "--all", usage = "Whether all of the tests should be run.")
  private boolean all = false;

  @Option(name = "--code-coverage", usage = "Whether code coverage information will be generated.")
  private boolean isCodeCoverageEnabled = false;

  @Option(name = "--debug", usage = "Whether the test will start suspended with a JDWP debug port of 5005")
  private boolean isDebugEnabled = false;

  @Option(name = "--xml", usage = "Where to write test output as XML.")
  @Nullable
  private String pathToXmlTestOutput = null;

  @Option(
      name = "--include",
      usage = "Labels to include when running tests, --include L1 L2 ... LN --other_option.",
      aliases = "-i",
      handler = StringSetOptionHandler.class)
  private Supplier<ImmutableSet<String>> includedSet;

  @Option(
      name = "--exclude",
      usage = "Labels to ignore when running tests, --exclude L1 L2 ... LN --other_option.",
      aliases = "-e",
      handler = StringSetOptionHandler.class)
  private Supplier<ImmutableSet<String>> excludedSet;

  private static ImmutableSet.Builder<String> validateLabels(Set<String> labelSet) {
    ImmutableSet.Builder<String> result = ImmutableSet.builder();
    for (String label : labelSet) {
      BuckConfig.validateLabelName(label);
    }
    result.addAll(labelSet);
    return result;
  }

  private Supplier<ImmutableSet<String>> includedLabelsSupplier =
      Suppliers.memoize(new Supplier<ImmutableSet<String>>() {
        @Override
        public ImmutableSet<String> get() {
          ImmutableSet.Builder<String> result = validateLabels(includedSet.get());
          return result.build();
        }
  });

  private Supplier<ImmutableSet<String>> excludedLabelsSupplier =
      Suppliers.memoize(new Supplier<ImmutableSet<String>>() {
        @Override
        public ImmutableSet<String> get() {
          ImmutableSet.Builder<String> result = validateLabels(excludedSet.get());
          result.addAll(getBuckConfig().getDefaultExcludedLabels());
          return result.build();
        }
  });

  public TestCommandOptions(BuckConfig buckConfig) {
    super(buckConfig);
  }

  public boolean isRunAllTests() {
    return all;
  }

  @Nullable
  public String getPathToXmlTestOutput() {
    return pathToXmlTestOutput;
  }

  public Optional<DefaultJavaPackageFinder> getJavaPackageFinder() {
    return Optional.fromNullable(getBuckConfig().createDefaultJavaPackageFinder());
  }

  @Override
  public boolean isCodeCoverageEnabled() {
    return isCodeCoverageEnabled;
  }

  @Override
  public boolean isDebugEnabled() {
    return isDebugEnabled;
  }

  public ImmutableSet<String> getIncludedLabels() {
    return includedLabelsSupplier.get();
  }

  public ImmutableSet<String> getExcludedLabels() {
    return excludedLabelsSupplier.get();
  }
}
