// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

package com.android.tools.r8;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import com.android.tools.r8.TestBase.Backend;
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.dex.Marker.Tool;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.google.common.collect.ImmutableList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;

public abstract class MarkerMatcher extends TypeSafeMatcher<Marker> {

  public static void assertMarkersMatch(Iterable<Marker> markers, Matcher<Marker> matcher) {
    assertMarkersMatch(markers, ImmutableList.of(matcher));
  }

  public static void assertMarkersMatch(
      Iterable<Marker> markers, Collection<Matcher<Marker>> matchers) {
    // Match is unordered, but we make no attempts to find the maximum match.
    int markerCount = 0;
    Set<Marker> matchedMarkers = new HashSet<>();
    Set<Matcher<Marker>> matchedMatchers = new HashSet<>();
    for (Marker marker : markers) {
      markerCount++;
      for (Matcher<Marker> matcher : matchers) {
        if (matchedMatchers.contains(matcher)) {
          continue;
        }
        if (matcher.matches(marker)) {
          matchedMarkers.add(marker);
          matchedMatchers.add(matcher);
          break;
        }
      }
    }
    StringBuilder builder = new StringBuilder();
    boolean failedMatching = false;
    if (matchedMarkers.size() < markerCount) {
      failedMatching = true;
      builder.append("\nUnmatched markers:");
      for (Marker marker : markers) {
        if (!matchedMarkers.contains(marker)) {
          builder.append("\n  - ").append(marker);
        }
      }
    }
    if (matchedMatchers.size() < matchers.size()) {
      failedMatching = true;
      builder.append("\nUnmatched matchers:");
      for (Matcher<Marker> matcher : matchers) {
        if (!matchedMatchers.contains(matcher)) {
          builder.append("\n  - ").append(matcher);
        }
      }
    }
    if (failedMatching) {
      builder.append("\nAll markers:");
      for (Marker marker : markers) {
        builder.append("\n  - ").append(marker);
      }
      builder.append("\nAll matchers:");
      for (Matcher<Marker> matcher : matchers) {
        builder.append("\n  - ").append(matcher);
      }
      fail(builder.toString());
    }
    // Double check consistency.
    assertEquals(matchers.size(), markerCount);
    assertEquals(markerCount, matchedMarkers.size());
    assertEquals(markerCount, matchedMatchers.size());
  }

  public static Matcher<Marker> markerTool(Tool tool) {
    return new MarkerMatcher() {
      @Override
      protected boolean eval(Marker marker) {
        return marker.getTool() == tool;
      }

      @Override
      protected void explain(Description description) {
        description.appendText("tool ").appendText(tool.name());
      }
    };
  }

  public static Matcher<Marker> markerCompilationMode(CompilationMode compilationMode) {
    return new MarkerMatcher() {
      @Override
      protected boolean eval(Marker marker) {
        return marker.getCompilationMode().equals(compilationMode.name().toLowerCase());
      }

      @Override
      protected void explain(Description description) {
        description.appendText(Marker.COMPILATION_MODE + " ").appendText(compilationMode.name());
      }
    };
  }

  public static Matcher<Marker> markerBackend(Backend backend) {
    return new MarkerMatcher() {
      @Override
      protected boolean eval(Marker marker) {
        return marker.getBackend().equals(backend.name().toLowerCase());
      }

      @Override
      protected void explain(Description description) {
        description.appendText(Marker.BACKEND + " ").appendText(backend.name().toLowerCase());
      }
    };
  }

  public static Matcher<Marker> markerIsDesugared() {
    return new MarkerMatcher() {
      @Override
      protected boolean eval(Marker marker) {
        return marker.isDesugared();
      }

      @Override
      protected void explain(Description description) {
        description.appendText("desugared ");
      }
    };
  }

  public static Matcher<Marker> markerMinApi(AndroidApiLevel level) {
    return new MarkerMatcher() {
      @Override
      protected boolean eval(Marker marker) {
        return marker.getMinApi() == level.getLevel();
      }

      @Override
      protected void explain(Description description) {
        description.appendText(Marker.MIN_API + " ").appendText(level.toString());
      }
    };
  }

  public static Matcher<Marker> markerHasMinApi() {
    return new MarkerMatcher() {
      @Override
      protected boolean eval(Marker marker) {
        return marker.hasMinApi();
      }

      @Override
      protected void explain(Description description) {
        description.appendText(Marker.MIN_API + " found");
      }
    };
  }

  public static Matcher<Marker> markerHasChecksums(boolean value) {
    return new MarkerMatcher() {
      @Override
      protected boolean eval(Marker marker) {
        return marker.getHasChecksums() == value;
      }

      @Override
      protected void explain(Description description) {
        description.appendText(Marker.HAS_CHECKSUMS + " ").appendText(Boolean.toString(value));
      }
    };
  }

  public static Matcher<Marker> markerR8Mode(String r8Mode) {
    return new MarkerMatcher() {
      @Override
      protected boolean eval(Marker marker) {
        return marker.getR8Mode().equals(r8Mode);
      }

      @Override
      protected void explain(Description description) {
        description.appendText(Marker.R8_MODE + " ").appendText(r8Mode);
      }
    };
  }

  public static Matcher<Marker> markerDesugaredLibraryIdentifier(
      String desugaredLibraryIdentifier) {
    return new MarkerMatcher() {
      @Override
      protected boolean eval(Marker marker) {
        if (marker.getDesugaredLibraryIdentifiers().length != 1) {
          return false;
        }
        return marker.getDesugaredLibraryIdentifiers()[0].equals(desugaredLibraryIdentifier);
      }

      @Override
      protected void explain(Description description) {
        description
            .appendText(Marker.DESUGARED_LIBRARY_IDENTIFIERS + " ")
            .appendText(desugaredLibraryIdentifier);
      }
    };
  }

  public static Matcher<Marker> markerHasDesugaredLibraryIdentifier() {
    return markerHasDesugaredLibraryIdentifier(true);
  }

  public static Matcher<Marker> markerHasDesugaredLibraryIdentifier(boolean value) {
    return new MarkerMatcher() {
      @Override
      protected boolean eval(Marker marker) {
        return marker.hasDesugaredLibraryIdentifiers() == value;
      }

      @Override
      protected void explain(Description description) {
        description.appendText(
            Marker.DESUGARED_LIBRARY_IDENTIFIERS + (value ? " found" : " not found"));
      }
    };
  }

  @Override
  protected boolean matchesSafely(Marker marker) {
    return eval(marker);
  }

  @Override
  public void describeTo(Description description) {
    explain(description.appendText("a marker "));
  }

  protected abstract boolean eval(Marker diagnostic);

  protected abstract void explain(Description description);
}
