/*
 * 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.test;

import com.facebook.buck.model.BuildTarget;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.annotations.Beta;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;

import java.util.List;

import javax.annotation.concurrent.Immutable;

/**
 * Represents the test results from multiple test cases.
 */
@Immutable
public class TestResults {

  private static final BuildTarget DUMMY_TARGET_FOR_TESTING = new BuildTarget("//foo/bar", "baz");

  private final BuildTarget source;
  private final ImmutableList<TestCaseSummary> testCases;
  private final ImmutableList<TestCaseSummary> failures;
  private final int failureCount;
  private final ImmutableSet<String> contacts;

  @VisibleForTesting
  public TestResults(List<TestCaseSummary> testCases) {
    this(DUMMY_TARGET_FOR_TESTING, testCases, /* contacts */ ImmutableSet.<String>of());
  }

  @Beta
  public TestResults(BuildTarget source,
      List<TestCaseSummary> testCases,
      ImmutableSet<String> contacts) {
    this.source = Preconditions.checkNotNull(source);
    this.testCases = ImmutableList.copyOf(testCases);
    this.contacts = ImmutableSet.copyOf(contacts);

    int failureCount = 0;
    ImmutableList.Builder<TestCaseSummary> failures = ImmutableList.builder();
    for (TestCaseSummary result : testCases) {
      if (!result.isSuccess()) {
        failures.add(result);
        failureCount += result.getFailureCount();
      }
    }
    this.failures = failures.build();
    this.failureCount = failureCount;
  }

  @JsonIgnore
  public BuildTarget getBuildTarget() {
    return source;
  }

  public boolean isSuccess() {
    return failures.isEmpty();
  }

  public int getFailureCount() {
    return failureCount;
  }

  @JsonIgnore
  public ImmutableList<TestCaseSummary> getFailures() {
    return failures;
  }

  public ImmutableList<TestCaseSummary> getTestCases() {
    return testCases;
  }

  @JsonIgnore
  public ImmutableSet<String> getContacts() {
    return contacts;
  }
}

