/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.beam.sdk.testing;

import static org.hamcrest.Matchers.in;
import static org.hamcrest.core.Is.is;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import javax.annotation.Nullable;
import org.apache.beam.sdk.coders.Coder;
import org.apache.beam.sdk.coders.CoderException;
import org.apache.beam.sdk.coders.ListCoder;
import org.apache.beam.sdk.util.CoderUtils;
import org.apache.beam.sdk.util.UserCodeException;
import org.apache.beam.sdk.values.KV;
import org.apache.beam.vendor.guava.v20_0.com.google.common.base.MoreObjects;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;

/**
 * Static class for building and using {@link SerializableMatcher} instances.
 *
 * <p>Most matchers are wrappers for hamcrest's {@link Matchers}. Please be familiar with the
 * documentation there. Values retained by a {@link SerializableMatcher} are required to be
 * serializable, either via Java serialization or via a provided {@link Coder}.
 *
 * <p>The following matchers are novel to Apache Beam:
 *
 * <ul>
 *   <li>{@link #kvWithKey} for matching just the key of a {@link KV}.
 *   <li>{@link #kvWithValue} for matching just the value of a {@link KV}.
 *   <li>{@link #kv} for matching the key and value of a {@link KV}.
 * </ul>
 *
 * <p>For example, to match a group from {@link org.apache.beam.sdk.transforms.GroupByKey}, which
 * has type {@code KV<K, Iterable<V>>} for some {@code K} and {@code V} and where the order of the
 * iterable is undefined, use a matcher like {@code kv(equalTo("some key"), containsInAnyOrder(1, 2,
 * 3))}.
 */
public class SerializableMatchers implements Serializable {

  // Serializable only because of capture by anonymous inner classes
  private SerializableMatchers() {} // not instantiable

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#allOf(Iterable)}. */
  public static <T> SerializableMatcher<T> allOf(
      Iterable<SerializableMatcher<? super T>> serializableMatchers) {

    @SuppressWarnings({"rawtypes", "unchecked"}) // safe covariant cast
    final Iterable<Matcher<? super T>> matchers = (Iterable) serializableMatchers;

    return fromSupplier(() -> Matchers.allOf(matchers));
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#allOf(Matcher[])}. */
  @SafeVarargs
  public static <T> SerializableMatcher<T> allOf(final SerializableMatcher<T>... matchers) {
    return fromSupplier(() -> Matchers.allOf(matchers));
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#anyOf(Iterable)}. */
  public static <T> SerializableMatcher<T> anyOf(
      Iterable<SerializableMatcher<? super T>> serializableMatchers) {

    @SuppressWarnings({"rawtypes", "unchecked"}) // safe covariant cast
    final Iterable<Matcher<? super T>> matchers = (Iterable) serializableMatchers;

    return fromSupplier(() -> Matchers.anyOf(matchers));
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#anyOf(Matcher[])}. */
  @SafeVarargs
  public static <T> SerializableMatcher<T> anyOf(final SerializableMatcher<T>... matchers) {
    return fromSupplier(() -> Matchers.anyOf(matchers));
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#anything()}. */
  public static SerializableMatcher<Object> anything() {
    return fromSupplier(Matchers::anything);
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#arrayContaining(Object[])}.
   */
  @SafeVarargs
  public static <T extends Serializable> SerializableMatcher<T[]> arrayContaining(
      final T... items) {
    return fromSupplier(() -> Matchers.arrayContaining(items));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#arrayContaining(Object[])}.
   *
   * <p>The items of type {@code T} will be serialized using the provided {@link Coder}. They are
   * explicitly <i>not</i> required or expected to be serializable via Java serialization.
   */
  @SafeVarargs
  public static <T> SerializableMatcher<T[]> arrayContaining(Coder<T> coder, T... items) {

    final SerializableSupplier<T[]> itemsSupplier = new SerializableArrayViaCoder<>(coder, items);

    return fromSupplier(() -> Matchers.arrayContaining(itemsSupplier.get()));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#arrayContaining(Matcher[])}.
   */
  @SafeVarargs
  public static <T> SerializableMatcher<T[]> arrayContaining(
      final SerializableMatcher<? super T>... matchers) {
    return fromSupplier(() -> Matchers.arrayContaining(matchers));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#arrayContaining(List)}.
   */
  public static <T> SerializableMatcher<T[]> arrayContaining(
      List<SerializableMatcher<? super T>> serializableMatchers) {

    @SuppressWarnings({"rawtypes", "unchecked"}) // safe covariant cast
    final List<Matcher<? super T>> matchers = (List) serializableMatchers;

    return fromSupplier(() -> Matchers.arrayContaining(matchers));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#arrayContainingInAnyOrder(Object[])}.
   */
  @SafeVarargs
  public static <T extends Serializable> SerializableMatcher<T[]> arrayContainingInAnyOrder(
      final T... items) {

    return fromSupplier(() -> Matchers.arrayContainingInAnyOrder(items));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#arrayContainingInAnyOrder(Object[])}.
   *
   * <p>The items of type {@code T} will be serialized using the provided {@link Coder}. They are
   * explicitly <i>not</i> required or expected to be serializable via Java serialization.
   */
  @SafeVarargs
  public static <T> SerializableMatcher<T[]> arrayContainingInAnyOrder(Coder<T> coder, T... items) {

    final SerializableSupplier<T[]> itemsSupplier = new SerializableArrayViaCoder<>(coder, items);

    return fromSupplier(() -> Matchers.arrayContaining(itemsSupplier.get()));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#arrayContainingInAnyOrder(Matcher[])}.
   */
  @SafeVarargs
  public static <T> SerializableMatcher<T[]> arrayContainingInAnyOrder(
      final SerializableMatcher<? super T>... matchers) {
    return fromSupplier(() -> Matchers.arrayContainingInAnyOrder(matchers));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#arrayContainingInAnyOrder(Collection)}.
   */
  public static <T> SerializableMatcher<T[]> arrayContainingInAnyOrder(
      Collection<SerializableMatcher<? super T>> serializableMatchers) {

    @SuppressWarnings({"rawtypes", "unchecked"}) // safe covariant cast
    final Collection<Matcher<? super T>> matchers = (Collection) serializableMatchers;

    return fromSupplier(() -> Matchers.arrayContainingInAnyOrder(matchers));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link Matchers#arrayWithSize(int)}.
   */
  public static <T> SerializableMatcher<T[]> arrayWithSize(final int size) {
    return fromSupplier(() -> Matchers.arrayWithSize(size));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#arrayWithSize(Matcher)}.
   */
  public static <T> SerializableMatcher<T[]> arrayWithSize(
      final SerializableMatcher<? super Integer> sizeMatcher) {
    return fromSupplier(() -> Matchers.arrayWithSize(sizeMatcher));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#closeTo(double,double)}.
   */
  public static SerializableMatcher<Double> closeTo(final double target, final double error) {
    return fromSupplier(() -> Matchers.closeTo(target, error));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link Matchers#contains(Object[])}.
   */
  @SafeVarargs
  public static <T extends Serializable> SerializableMatcher<Iterable<? extends T>> contains(
      final T... items) {
    return fromSupplier(() -> Matchers.contains(items));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link Matchers#contains(Object[])}.
   *
   * <p>The items of type {@code T} will be serialized using the provided {@link Coder}. They are
   * explicitly <i>not</i> required or expected to be serializable via Java serialization.
   */
  @SafeVarargs
  public static <T> SerializableMatcher<Iterable<? extends T>> contains(
      Coder<T> coder, T... items) {

    final SerializableSupplier<T[]> itemsSupplier = new SerializableArrayViaCoder<>(coder, items);

    return fromSupplier(() -> Matchers.containsInAnyOrder(itemsSupplier.get()));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link Matchers#contains(Matcher[])}.
   */
  @SafeVarargs
  public static <T> SerializableMatcher<Iterable<? extends T>> contains(
      final SerializableMatcher<? super T>... matchers) {
    return fromSupplier(() -> Matchers.contains(matchers));
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#contains(List)}. */
  public static <T extends Serializable> SerializableMatcher<Iterable<? extends T>> contains(
      List<SerializableMatcher<? super T>> serializableMatchers) {

    @SuppressWarnings({"rawtypes", "unchecked"}) // safe covariant cast
    final List<Matcher<? super T>> matchers = (List) serializableMatchers;

    return fromSupplier(() -> Matchers.contains(matchers));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#containsInAnyOrder(Object[])}.
   */
  @SafeVarargs
  public static <T extends Serializable>
      SerializableMatcher<Iterable<? extends T>> containsInAnyOrder(final T... items) {
    return fromSupplier(() -> Matchers.containsInAnyOrder(items));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#containsInAnyOrder(Object[])}.
   *
   * <p>The items of type {@code T} will be serialized using the provided {@link Coder}. It is
   * explicitly <i>not</i> required or expected to be serializable via Java serialization.
   */
  @SafeVarargs
  public static <T> SerializableMatcher<Iterable<? extends T>> containsInAnyOrder(
      Coder<T> coder, T... items) {

    final SerializableSupplier<T[]> itemsSupplier = new SerializableArrayViaCoder<>(coder, items);

    return fromSupplier(() -> Matchers.containsInAnyOrder(itemsSupplier.get()));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#containsInAnyOrder(Matcher[])}.
   */
  @SafeVarargs
  public static <T> SerializableMatcher<Iterable<? extends T>> containsInAnyOrder(
      final SerializableMatcher<? super T>... matchers) {
    return fromSupplier(() -> Matchers.containsInAnyOrder(matchers));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#containsInAnyOrder(Collection)}.
   */
  public static <T> SerializableMatcher<Iterable<? extends T>> containsInAnyOrder(
      Collection<SerializableMatcher<? super T>> serializableMatchers) {

    @SuppressWarnings({"rawtypes", "unchecked"}) // safe covariant cast
    final Collection<Matcher<? super T>> matchers = (Collection) serializableMatchers;

    return fromSupplier(() -> Matchers.containsInAnyOrder(matchers));
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#containsString}. */
  public static SerializableMatcher<String> containsString(final String substring) {
    return fromSupplier(() -> Matchers.containsString(substring));
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#empty()}. */
  public static <T> SerializableMatcher<Collection<? extends T>> empty() {
    return fromSupplier(Matchers::empty);
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#emptyArray()}. */
  public static <T> SerializableMatcher<T[]> emptyArray() {
    return fromSupplier(Matchers::emptyArray);
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#emptyIterable()}. */
  public static <T> SerializableMatcher<Iterable<? extends T>> emptyIterable() {
    return fromSupplier(Matchers::emptyIterable);
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#endsWith}. */
  public static SerializableMatcher<String> endsWith(final String substring) {
    return fromSupplier(() -> Matchers.endsWith(substring));
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#equalTo(Object)}. */
  public static <T extends Serializable> SerializableMatcher<T> equalTo(final T expected) {
    return fromSupplier(() -> Matchers.equalTo(expected));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link Matchers#equalTo(Object)}.
   *
   * <p>The expected value of type {@code T} will be serialized using the provided {@link Coder}. It
   * is explicitly <i>not</i> required or expected to be serializable via Java serialization.
   */
  public static <T> SerializableMatcher<T> equalTo(Coder<T> coder, T expected) {

    final SerializableSupplier<T> expectedSupplier = new SerializableViaCoder<>(coder, expected);

    return fromSupplier(() -> Matchers.equalTo(expectedSupplier.get()));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#greaterThan(Comparable)}.
   */
  public static <T extends Comparable<T> & Serializable> SerializableMatcher<T> greaterThan(
      final T target) {
    return fromSupplier(() -> Matchers.greaterThan(target));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#greaterThan(Comparable)}.
   *
   * <p>The target value of type {@code T} will be serialized using the provided {@link Coder}. It
   * is explicitly <i>not</i> required or expected to be serializable via Java serialization.
   */
  public static <T extends Comparable<T> & Serializable> SerializableMatcher<T> greaterThan(
      final Coder<T> coder, T target) {
    final SerializableSupplier<T> targetSupplier = new SerializableViaCoder<>(coder, target);
    return fromSupplier(() -> Matchers.greaterThan(targetSupplier.get()));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#greaterThanOrEqualTo(Comparable)}.
   */
  public static <T extends Comparable<T>> SerializableMatcher<T> greaterThanOrEqualTo(
      final T target) {
    return fromSupplier(() -> Matchers.greaterThanOrEqualTo(target));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#greaterThanOrEqualTo(Comparable)}.
   *
   * <p>The target value of type {@code T} will be serialized using the provided {@link Coder}. It
   * is explicitly <i>not</i> required or expected to be serializable via Java serialization.
   */
  public static <T extends Comparable<T> & Serializable>
      SerializableMatcher<T> greaterThanOrEqualTo(final Coder<T> coder, T target) {
    final SerializableSupplier<T> targetSupplier = new SerializableViaCoder<>(coder, target);
    return fromSupplier(() -> Matchers.greaterThanOrEqualTo(targetSupplier.get()));
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#hasItem(Object)}. */
  public static <T extends Serializable> SerializableMatcher<Iterable<? super T>> hasItem(
      final T target) {
    return fromSupplier(() -> Matchers.hasItem(target));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link Matchers#hasItem(Object)}.
   *
   * <p>The item of type {@code T} will be serialized using the provided {@link Coder}. It is
   * explicitly <i>not</i> required or expected to be serializable via Java serialization.
   */
  public static <T> SerializableMatcher<Iterable<? super T>> hasItem(Coder<T> coder, T target) {
    final SerializableSupplier<T> targetSupplier = new SerializableViaCoder<>(coder, target);
    return fromSupplier(() -> Matchers.hasItem(targetSupplier.get()));
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#hasItem(Matcher)}. */
  public static <T> SerializableMatcher<Iterable<? super T>> hasItem(
      final SerializableMatcher<? super T> matcher) {
    return fromSupplier(() -> Matchers.hasItem(matcher));
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#hasSize(int)}. */
  public static <T> SerializableMatcher<Collection<? extends T>> hasSize(final int size) {
    return fromSupplier(() -> Matchers.hasSize(size));
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#hasSize(Matcher)}. */
  public static <T> SerializableMatcher<Collection<? extends T>> hasSize(
      final SerializableMatcher<? super Integer> sizeMatcher) {
    return fromSupplier(() -> Matchers.hasSize(sizeMatcher));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#iterableWithSize(int)}.
   */
  public static <T> SerializableMatcher<Iterable<T>> iterableWithSize(final int size) {
    return fromSupplier(() -> Matchers.iterableWithSize(size));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#iterableWithSize(Matcher)}.
   */
  public static <T> SerializableMatcher<Iterable<T>> iterableWithSize(
      final SerializableMatcher<? super Integer> sizeMatcher) {
    return fromSupplier(() -> Matchers.iterableWithSize(sizeMatcher));
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#isIn(Collection)}. */
  public static <T extends Serializable> SerializableMatcher<T> isIn(
      final Collection<T> collection) {
    return fromSupplier(() -> is(in(collection)));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link Matchers#isIn(Collection)}.
   *
   * <p>The items of type {@code T} will be serialized using the provided {@link Coder}. They are
   * explicitly <i>not</i> required or expected to be serializable via Java serialization.
   */
  public static <T> SerializableMatcher<T> isIn(Coder<T> coder, Collection<T> collection) {
    @SuppressWarnings("unchecked")
    T[] items = (T[]) collection.toArray();
    final SerializableSupplier<T[]> itemsSupplier = new SerializableArrayViaCoder<>(coder, items);
    return fromSupplier(() -> is(in(itemsSupplier.get())));
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#isIn(Object[])}. */
  public static <T extends Serializable> SerializableMatcher<T> isIn(final T[] items) {
    return fromSupplier(() -> is(in(items)));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link Matchers#isIn(Object[])}.
   *
   * <p>The items of type {@code T} will be serialized using the provided {@link Coder}. They are
   * explicitly <i>not</i> required or expected to be serializable via Java serialization.
   */
  public static <T> SerializableMatcher<T> isIn(Coder<T> coder, T[] items) {
    final SerializableSupplier<T[]> itemsSupplier = new SerializableArrayViaCoder<>(coder, items);
    return fromSupplier(() -> is(in(itemsSupplier.get())));
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#isOneOf}. */
  @SafeVarargs
  public static <T extends Serializable> SerializableMatcher<T> isOneOf(final T... elems) {
    return fromSupplier(() -> Matchers.isOneOf(elems));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link Matchers#isOneOf}.
   *
   * <p>The items of type {@code T} will be serialized using the provided {@link Coder}. They are
   * explicitly <i>not</i> required or expected to be serializable via Java serialization.
   */
  @SafeVarargs
  public static <T> SerializableMatcher<T> isOneOf(Coder<T> coder, T... items) {
    final SerializableSupplier<T[]> itemsSupplier = new SerializableArrayViaCoder<>(coder, items);
    return fromSupplier(() -> Matchers.isOneOf(itemsSupplier.get()));
  }

  /** A {@link SerializableMatcher} that matches any {@link KV} with the specified key. */
  public static <K extends Serializable, V>
      SerializableMatcher<KV<? extends K, ? extends V>> kvWithKey(K key) {
    return new KvKeyMatcher<>(equalTo(key));
  }

  /**
   * A {@link SerializableMatcher} that matches any {@link KV} with the specified key.
   *
   * <p>The key of type {@code K} will be serialized using the provided {@link Coder}. It is
   * explicitly <i>not</i> required or expected to be serializable via Java serialization.
   */
  public static <K, V> SerializableMatcher<KV<? extends K, ? extends V>> kvWithKey(
      Coder<K> coder, K key) {
    return new KvKeyMatcher<>(equalTo(coder, key));
  }

  /** A {@link SerializableMatcher} that matches any {@link KV} with matching key. */
  public static <K, V> SerializableMatcher<KV<? extends K, ? extends V>> kvWithKey(
      final SerializableMatcher<? super K> keyMatcher) {
    return new KvKeyMatcher<>(keyMatcher);
  }

  /** A {@link SerializableMatcher} that matches any {@link KV} with the specified value. */
  public static <K, V extends Serializable>
      SerializableMatcher<KV<? extends K, ? extends V>> kvWithValue(V value) {
    return new KvValueMatcher<>(equalTo(value));
  }

  /**
   * A {@link SerializableMatcher} that matches any {@link KV} with the specified value.
   *
   * <p>The value of type {@code V} will be serialized using the provided {@link Coder}. It is
   * explicitly <i>not</i> required or expected to be serializable via Java serialization.
   */
  public static <K, V> SerializableMatcher<KV<? extends K, ? extends V>> kvWithValue(
      Coder<V> coder, V value) {
    return new KvValueMatcher<>(equalTo(coder, value));
  }

  /** A {@link SerializableMatcher} that matches any {@link KV} with matching value. */
  public static <K, V> SerializableMatcher<KV<? extends K, ? extends V>> kvWithValue(
      final SerializableMatcher<? super V> valueMatcher) {
    return new KvValueMatcher<>(valueMatcher);
  }

  /** A {@link SerializableMatcher} that matches any {@link KV} with matching key and value. */
  public static <K, V> SerializableMatcher<KV<? extends K, ? extends V>> kv(
      final SerializableMatcher<? super K> keyMatcher,
      final SerializableMatcher<? super V> valueMatcher) {

    return SerializableMatchers.allOf(
        SerializableMatchers.kvWithKey(keyMatcher), SerializableMatchers.kvWithValue(valueMatcher));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link Matchers#lessThan(Comparable)}.
   */
  public static <T extends Comparable<T> & Serializable> SerializableMatcher<T> lessThan(
      final T target) {
    return fromSupplier(() -> Matchers.lessThan(target));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link Matchers#lessThan(Comparable)}.
   *
   * <p>The target value of type {@code T} will be serialized using the provided {@link Coder}. It
   * is explicitly <i>not</i> required or expected to be serializable via Java serialization.
   */
  public static <T extends Comparable<T>> SerializableMatcher<T> lessThan(
      Coder<T> coder, T target) {
    final SerializableSupplier<T> targetSupplier = new SerializableViaCoder<>(coder, target);
    return fromSupplier(() -> Matchers.lessThan(targetSupplier.get()));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#lessThanOrEqualTo(Comparable)}.
   */
  public static <T extends Comparable<T> & Serializable> SerializableMatcher<T> lessThanOrEqualTo(
      final T target) {
    return fromSupplier(() -> Matchers.lessThanOrEqualTo(target));
  }

  /**
   * A {@link SerializableMatcher} with identical criteria to {@link
   * Matchers#lessThanOrEqualTo(Comparable)}.
   *
   * <p>The target value of type {@code T} will be serialized using the provided {@link Coder}. It
   * is explicitly <i>not</i> required or expected to be serializable via Java serialization.
   */
  public static <T extends Comparable<T>> SerializableMatcher<T> lessThanOrEqualTo(
      Coder<T> coder, T target) {
    final SerializableSupplier<T> targetSupplier = new SerializableViaCoder<>(coder, target);
    return fromSupplier(() -> Matchers.lessThanOrEqualTo(targetSupplier.get()));
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#not}. */
  public static <T> SerializableMatcher<T> not(final SerializableMatcher<T> matcher) {
    return fromSupplier(() -> Matchers.not(matcher));
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#nullValue}. */
  public static SerializableMatcher<Object> nullValue() {
    return fromSupplier(Matchers::nullValue);
  }

  /** A {@link SerializableMatcher} with identical criteria to {@link Matchers#startsWith}. */
  public static SerializableMatcher<String> startsWith(final String substring) {
    return fromSupplier(() -> Matchers.startsWith(substring));
  }

  private static class KvKeyMatcher<K, V> extends BaseMatcher<KV<? extends K, ? extends V>>
      implements SerializableMatcher<KV<? extends K, ? extends V>> {
    private final SerializableMatcher<? super K> keyMatcher;

    public KvKeyMatcher(SerializableMatcher<? super K> keyMatcher) {
      this.keyMatcher = keyMatcher;
    }

    @Override
    public boolean matches(Object item) {
      @SuppressWarnings("unchecked")
      KV<K, ?> kvItem = (KV<K, ?>) item;
      return keyMatcher.matches(kvItem.getKey());
    }

    @Override
    public void describeMismatch(Object item, Description mismatchDescription) {
      @SuppressWarnings("unchecked")
      KV<K, ?> kvItem = (KV<K, ?>) item;
      if (!keyMatcher.matches(kvItem.getKey())) {
        mismatchDescription.appendText("key did not match: ");
        keyMatcher.describeMismatch(kvItem.getKey(), mismatchDescription);
      }
    }

    @Override
    public void describeTo(Description description) {
      description.appendText("KV with key matching ");
      keyMatcher.describeTo(description);
    }

    @Override
    public String toString() {
      return MoreObjects.toStringHelper(this).addValue(keyMatcher).toString();
    }
  }

  private static class KvValueMatcher<K, V> extends BaseMatcher<KV<? extends K, ? extends V>>
      implements SerializableMatcher<KV<? extends K, ? extends V>> {
    private final SerializableMatcher<? super V> valueMatcher;

    public KvValueMatcher(SerializableMatcher<? super V> valueMatcher) {
      this.valueMatcher = valueMatcher;
    }

    @Override
    public boolean matches(Object item) {
      @SuppressWarnings("unchecked")
      KV<?, V> kvItem = (KV<?, V>) item;
      return valueMatcher.matches(kvItem.getValue());
    }

    @Override
    public void describeMismatch(Object item, Description mismatchDescription) {
      @SuppressWarnings("unchecked")
      KV<?, V> kvItem = (KV<?, V>) item;
      if (!valueMatcher.matches(kvItem.getValue())) {
        mismatchDescription.appendText("value did not match: ");
        valueMatcher.describeMismatch(kvItem.getValue(), mismatchDescription);
      }
    }

    @Override
    public void describeTo(Description description) {
      description.appendText("KV with value matching ");
      valueMatcher.describeTo(description);
    }

    @Override
    public String toString() {
      return MoreObjects.toStringHelper(this).addValue(valueMatcher).toString();
    }
  }

  /**
   * Constructs a {@link SerializableMatcher} from a non-serializable {@link Matcher} via
   * indirection through {@link SerializableSupplier}.
   *
   * <p>To wrap a {@link Matcher} which is not serializable, provide a {@link SerializableSupplier}
   * with a {@link SerializableSupplier#get()} method that returns a fresh instance of the {@link
   * Matcher} desired. The resulting {@link SerializableMatcher} will behave according to the {@link
   * Matcher} returned by {@link SerializableSupplier#get() get()} when it is invoked during
   * matching (which may occur on another machine).
   *
   * <pre>{@code
   * return fromSupplier(new SerializableSupplier<Matcher<T>>() {
   *   *     @Override
   *     public Matcher<T> get() {
   *       return new MyMatcherForT();
   *     }
   * });
   * }</pre>
   */
  public static <T> SerializableMatcher<T> fromSupplier(SerializableSupplier<Matcher<T>> supplier) {
    return new SerializableMatcherFromSupplier<>(supplier);
  }

  /**
   * Supplies values of type {@code T}, and is serializable. Thus, even if {@code T} is not
   * serializable, the supplier can be serialized and provide a {@code T} wherever it is
   * deserialized.
   *
   * @param <T> the type of value supplied.
   */
  public interface SerializableSupplier<T> extends Serializable {
    T get();
  }

  /**
   * Since the delegate {@link Matcher} is not generally serializable, instead this takes a nullary
   * SerializableFunction to return such a matcher.
   */
  private static class SerializableMatcherFromSupplier<T> extends BaseMatcher<T>
      implements SerializableMatcher<T> {

    private SerializableSupplier<Matcher<T>> supplier;

    public SerializableMatcherFromSupplier(SerializableSupplier<Matcher<T>> supplier) {
      this.supplier = supplier;
    }

    @Override
    public void describeTo(Description description) {
      supplier.get().describeTo(description);
    }

    @Override
    public boolean matches(Object item) {
      return supplier.get().matches(item);
    }

    @Override
    public void describeMismatch(Object item, Description mismatchDescription) {
      supplier.get().describeMismatch(item, mismatchDescription);
    }
  }

  /**
   * Wraps any value that can be encoded via a {@link Coder} to make it {@link Serializable}. This
   * is not likely to be a good encoding, so should be used only for tests, where data volume is
   * small and minor costs are not critical.
   */
  private static class SerializableViaCoder<T> implements SerializableSupplier<T> {
    /** Cached value that is not serialized. */
    @Nullable private transient T value;

    /** The bytes of {@link #value} when encoded via {@link #coder}. */
    private byte[] encodedValue;

    private Coder<T> coder;

    public SerializableViaCoder(Coder<T> coder, T value) {
      this.coder = coder;
      this.value = value;
      try {
        this.encodedValue = CoderUtils.encodeToByteArray(coder, value);
      } catch (CoderException exc) {
        throw new RuntimeException("Error serializing via Coder", exc);
      }
    }

    @Override
    public T get() {
      if (value == null) {
        try {
          value = CoderUtils.decodeFromByteArray(coder, encodedValue);
        } catch (CoderException exc) {
          throw new RuntimeException("Error deserializing via Coder", exc);
        }
      }
      return value;
    }
  }

  /**
   * Wraps any array with values that can be encoded via a {@link Coder} to make it {@link
   * Serializable}. This is not likely to be a good encoding, so should be used only for tests,
   * where data volume is small and minor costs are not critical.
   */
  private static class SerializableArrayViaCoder<T> implements SerializableSupplier<T[]> {
    /** Cached value that is not serialized. */
    @Nullable private transient T[] value;

    /** The bytes of {@link #value} when encoded via {@link #coder}. */
    private byte[] encodedValue;

    private Coder<List<T>> coder;

    public SerializableArrayViaCoder(Coder<T> elementCoder, T[] value) {
      this.coder = ListCoder.of(elementCoder);
      this.value = value;
      try {
        this.encodedValue = CoderUtils.encodeToByteArray(coder, Arrays.asList(value));
      } catch (CoderException exc) {
        throw UserCodeException.wrap(exc);
      }
    }

    @Override
    public T[] get() {
      if (value == null) {
        try {
          @SuppressWarnings("unchecked")
          T[] decoded = (T[]) CoderUtils.decodeFromByteArray(coder, encodedValue).toArray();
          value = decoded;
        } catch (CoderException exc) {
          throw new RuntimeException("Error deserializing via Coder", exc);
        }
      }
      return value;
    }
  }
}
