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

import static org.apache.beam.sdk.transforms.display.DisplayDataMatchers.hasDisplayItem;
import static org.apache.beam.sdk.transforms.display.DisplayDataMatchers.hasKey;
import static org.apache.beam.sdk.transforms.display.DisplayDataMatchers.hasLabel;
import static org.apache.beam.sdk.transforms.display.DisplayDataMatchers.hasNamespace;
import static org.apache.beam.sdk.transforms.display.DisplayDataMatchers.hasPath;
import static org.apache.beam.sdk.transforms.display.DisplayDataMatchers.hasType;
import static org.apache.beam.sdk.transforms.display.DisplayDataMatchers.hasValue;
import static org.apache.beam.sdk.transforms.display.DisplayDataMatchers.includesDisplayDataFor;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.everyItem;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isA;
import static org.hamcrest.Matchers.isEmptyOrNullString;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.auto.value.AutoValue;
import com.google.common.testing.EqualsTester;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.beam.sdk.options.ValueProvider;
import org.apache.beam.sdk.options.ValueProvider.StaticValueProvider;
import org.apache.beam.sdk.transforms.PTransform;
import org.apache.beam.sdk.transforms.display.DisplayData.Builder;
import org.apache.beam.sdk.transforms.display.DisplayData.Item;
import org.apache.beam.sdk.util.SerializableUtils;
import org.apache.beam.sdk.values.PCollection;
import org.apache.beam.vendor.guava.v20_0.com.google.common.collect.ImmutableMap;
import org.apache.beam.vendor.guava.v20_0.com.google.common.collect.ImmutableMultimap;
import org.apache.beam.vendor.guava.v20_0.com.google.common.collect.Iterables;
import org.apache.beam.vendor.guava.v20_0.com.google.common.collect.Multimap;
import org.hamcrest.CustomTypeSafeMatcher;
import org.hamcrest.FeatureMatcher;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import org.joda.time.Duration;
import org.joda.time.Instant;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link DisplayData} class. */
@RunWith(JUnit4.class)
public class DisplayDataTest implements Serializable {
  @Rule public transient ExpectedException thrown = ExpectedException.none();

  private static final DateTimeFormatter ISO_FORMATTER = ISODateTimeFormat.dateTime();
  private static final ObjectMapper MAPPER = new ObjectMapper();

  @Test
  public void testTypicalUsage() {
    final HasDisplayData subComponent1 =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(DisplayData.Builder builder) {
            builder.add(DisplayData.item("ExpectedAnswer", 42));
          }
        };

    final HasDisplayData subComponent2 =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(DisplayData.Builder builder) {
            builder
                .add(DisplayData.item("Location", "Seattle"))
                .add(DisplayData.item("Forecast", "Rain"));
          }
        };

    PTransform<?, ?> transform =
        new PTransform<PCollection<String>, PCollection<String>>() {
          final Instant defaultStartTime = new Instant(0);
          Instant startTime = defaultStartTime;

          @Override
          public PCollection<String> expand(PCollection<String> begin) {
            throw new IllegalArgumentException("Should never be applied");
          }

          @Override
          public void populateDisplayData(DisplayData.Builder builder) {
            builder
                .include("p1", subComponent1)
                .include("p2", subComponent2)
                .add(DisplayData.item("minSproggles", 200).withLabel("Minimum Required Sproggles"))
                .add(DisplayData.item("fireLasers", true))
                .addIfNotDefault(DisplayData.item("startTime", startTime), defaultStartTime)
                .add(DisplayData.item("timeBomb", Instant.now().plus(Duration.standardDays(1))))
                .add(DisplayData.item("filterLogic", subComponent1.getClass()))
                .add(
                    DisplayData.item("serviceUrl", "google.com/fizzbang")
                        .withLinkUrl("http://www.google.com/fizzbang"));
          }
        };

    DisplayData data = DisplayData.from(transform);

    assertThat(data.items(), not(empty()));
    assertThat(
        data.items(),
        everyItem(
            allOf(
                hasKey(not(isEmptyOrNullString())),
                hasNamespace(
                    Matchers.<Class<?>>isOneOf(
                        transform.getClass(), subComponent1.getClass(), subComponent2.getClass())),
                hasType(notNullValue(DisplayData.Type.class)),
                hasValue(not(isEmptyOrNullString())))));
  }

  @Test
  public void testDefaultInstance() {
    DisplayData none = DisplayData.none();
    assertThat(none.items(), empty());
  }

  @Test
  public void testCanBuildDisplayData() {
    DisplayData data =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(DisplayData.Builder builder) {
                builder.add(DisplayData.item("foo", "bar"));
              }
            });

    assertThat(data.items(), hasSize(1));
    assertThat(data, hasDisplayItem("foo", "bar"));
  }

  @Test
  public void testStaticValueProviderDate() {
    final Instant value = Instant.now();
    DisplayData data =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(DisplayData.Builder builder) {
                builder.add(DisplayData.item("foo", StaticValueProvider.of(value)));
              }
            });

    @SuppressWarnings("unchecked")
    DisplayData.Item item = (DisplayData.Item) data.items().toArray()[0];

    @SuppressWarnings("unchecked")
    Matcher<Item> matchesAllOf =
        allOf(
            hasKey("foo"),
            hasType(DisplayData.Type.TIMESTAMP),
            hasValue(ISO_FORMATTER.print(value)));

    assertThat(item, matchesAllOf);
  }

  @Test
  public void testStaticValueProviderString() {
    DisplayData data =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(DisplayData.Builder builder) {
                builder.add(DisplayData.item("foo", StaticValueProvider.of("bar")));
              }
            });

    assertThat(data.items(), hasSize(1));
    assertThat(data, hasDisplayItem("foo", "bar"));
  }

  @Test
  public void testStaticValueProviderInt() {
    DisplayData data =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(DisplayData.Builder builder) {
                builder.add(DisplayData.item("foo", StaticValueProvider.of(1)));
              }
            });

    assertThat(data.items(), hasSize(1));
    assertThat(data, hasDisplayItem("foo", 1));
  }

  @Test
  public void testInaccessibleValueProvider() {
    DisplayData data =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(DisplayData.Builder builder) {
                builder.add(
                    DisplayData.item(
                        "foo",
                        new ValueProvider<String>() {
                          @Override
                          public boolean isAccessible() {
                            return false;
                          }

                          @Override
                          public String get() {
                            return "bar";
                          }

                          @Override
                          public String toString() {
                            return "toString";
                          }
                        }));
              }
            });

    assertThat(data.items(), hasSize(1));
    assertThat(data, hasDisplayItem("foo", "toString"));
  }

  @Test
  public void testAsMap() {
    DisplayData data =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(DisplayData.Builder builder) {
                builder.add(DisplayData.item("foo", "bar"));
              }
            });

    Map<DisplayData.Identifier, DisplayData.Item> map = data.asMap();
    assertEquals(1, map.size());
    assertThat(data, hasDisplayItem("foo", "bar"));
    assertEquals(map.values(), data.items());
  }

  @Test
  public void testItemProperties() {
    final Instant value = Instant.now();
    DisplayData data =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(DisplayData.Builder builder) {
                builder.add(
                    DisplayData.item("now", value)
                        .withLabel("the current instant")
                        .withLinkUrl("http://time.gov")
                        .withNamespace(DisplayDataTest.class));
              }
            });

    @SuppressWarnings("unchecked")
    DisplayData.Item item = (DisplayData.Item) data.items().toArray()[0];

    @SuppressWarnings("unchecked")
    Matcher<Item> matchesAllOf =
        allOf(
            hasNamespace(DisplayDataTest.class),
            hasKey("now"),
            hasType(DisplayData.Type.TIMESTAMP),
            hasValue(ISO_FORMATTER.print(value)),
            hasShortValue(nullValue(String.class)),
            hasLabel("the current instant"),
            hasUrl(is("http://time.gov")));

    assertThat(item, matchesAllOf);
  }

  @Test
  public void testUnspecifiedOptionalProperties() {
    DisplayData data =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(DisplayData.Builder builder) {
                builder.add(DisplayData.item("foo", "bar"));
              }
            });

    assertThat(
        data,
        hasDisplayItem(allOf(hasLabel(nullValue(String.class)), hasUrl(nullValue(String.class)))));
  }

  @Test
  public void testAddIfNotDefault() {
    DisplayData data =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(Builder builder) {
                builder
                    .addIfNotDefault(DisplayData.item("defaultString", "foo"), "foo")
                    .addIfNotDefault(DisplayData.item("notDefaultString", "foo"), "notFoo")
                    .addIfNotDefault(DisplayData.item("defaultInteger", 1), 1)
                    .addIfNotDefault(DisplayData.item("notDefaultInteger", 1), 2)
                    .addIfNotDefault(DisplayData.item("defaultDouble", 123.4), 123.4)
                    .addIfNotDefault(DisplayData.item("notDefaultDouble", 123.4), 234.5)
                    .addIfNotDefault(DisplayData.item("defaultBoolean", true), true)
                    .addIfNotDefault(DisplayData.item("notDefaultBoolean", true), false)
                    .addIfNotDefault(
                        DisplayData.item("defaultInstant", new Instant(0)), new Instant(0))
                    .addIfNotDefault(
                        DisplayData.item("notDefaultInstant", new Instant(0)), Instant.now())
                    .addIfNotDefault(
                        DisplayData.item("defaultDuration", Duration.ZERO), Duration.ZERO)
                    .addIfNotDefault(
                        DisplayData.item("notDefaultDuration", Duration.millis(1234)),
                        Duration.ZERO)
                    .addIfNotDefault(
                        DisplayData.item("defaultClass", DisplayDataTest.class),
                        DisplayDataTest.class)
                    .addIfNotDefault(
                        DisplayData.item("notDefaultClass", DisplayDataTest.class), null);
              }
            });

    assertThat(data.items(), hasSize(7));
    assertThat(data.items(), everyItem(hasKey(startsWith("notDefault"))));
  }

  @Test
  @SuppressWarnings("UnnecessaryBoxing")
  public void testInterpolatedTypeDefaults() {
    DisplayData data =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(Builder builder) {
                builder
                    .addIfNotDefault(DisplayData.item("integer", 123), 123)
                    .addIfNotDefault(
                        DisplayData.item("Integer", Integer.valueOf(123)), Integer.valueOf(123))
                    .addIfNotDefault(DisplayData.item("long", 123L), 123L)
                    .addIfNotDefault(DisplayData.item("Long", Long.valueOf(123)), Long.valueOf(123))
                    .addIfNotDefault(DisplayData.item("float", 1.23f), 1.23f)
                    .addIfNotDefault(
                        DisplayData.item("Float", Float.valueOf(1.23f)), Float.valueOf(1.23f))
                    .addIfNotDefault(DisplayData.item("double", 1.23), 1.23)
                    .addIfNotDefault(
                        DisplayData.item("Double", Double.valueOf(1.23)), Double.valueOf(1.23))
                    .addIfNotDefault(DisplayData.item("boolean", true), true)
                    .addIfNotDefault(DisplayData.item("Boolean", Boolean.TRUE), Boolean.TRUE);
              }
            });

    assertThat(data.items(), empty());
  }

  @Test
  public void testAddIfNotNull() {
    DisplayData data =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(Builder builder) {
                builder
                    .addIfNotNull(DisplayData.item("nullString", (String) null))
                    .addIfNotNull(DisplayData.item("nullVPString", (ValueProvider<String>) null))
                    .addIfNotNull(DisplayData.item("nullierVPString", StaticValueProvider.of(null)))
                    .addIfNotNull(DisplayData.item("notNullString", "foo"))
                    .addIfNotNull(DisplayData.item("nullLong", (Long) null))
                    .addIfNotNull(DisplayData.item("notNullLong", 1234L))
                    .addIfNotNull(DisplayData.item("nullDouble", (Double) null))
                    .addIfNotNull(DisplayData.item("notNullDouble", 123.4))
                    .addIfNotNull(DisplayData.item("nullBoolean", (Boolean) null))
                    .addIfNotNull(DisplayData.item("notNullBoolean", true))
                    .addIfNotNull(DisplayData.item("nullInstant", (Instant) null))
                    .addIfNotNull(DisplayData.item("notNullInstant", Instant.now()))
                    .addIfNotNull(DisplayData.item("nullDuration", (Duration) null))
                    .addIfNotNull(DisplayData.item("notNullDuration", Duration.ZERO))
                    .addIfNotNull(DisplayData.item("nullClass", (Class<?>) null))
                    .addIfNotNull(DisplayData.item("notNullClass", DisplayDataTest.class));
              }
            });

    assertThat(data.items(), hasSize(7));
    assertThat(data.items(), everyItem(hasKey(startsWith("notNull"))));
  }

  @Test
  public void testModifyingConditionalItemIsSafe() {
    HasDisplayData component =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.addIfNotNull(
                DisplayData.item("nullItem", (Class<?>) null)
                    .withLinkUrl("http://abc")
                    .withNamespace(DisplayDataTest.class)
                    .withLabel("Null item should be safe"));
          }
        };

    DisplayData.from(component); // should not throw
  }

  @Test
  public void testRootPath() {
    DisplayData.Path root = DisplayData.Path.root();
    assertThat(root.getComponents(), empty());
  }

  @Test
  public void testExtendPath() {
    DisplayData.Path a = DisplayData.Path.root().extend("a");
    assertThat(a.getComponents(), hasItems("a"));

    DisplayData.Path b = a.extend("b");
    assertThat(b.getComponents(), hasItems("a", "b"));
  }

  @Test
  public void testExtendNullPathValidation() {
    DisplayData.Path root = DisplayData.Path.root();
    thrown.expect(NullPointerException.class);
    root.extend(null);
  }

  @Test
  public void testExtendEmptyPathValidation() {
    DisplayData.Path root = DisplayData.Path.root();
    thrown.expect(IllegalArgumentException.class);
    root.extend("");
  }

  @Test
  public void testAbsolute() {
    DisplayData.Path path = DisplayData.Path.absolute("a", "b", "c");
    assertThat(path.getComponents(), hasItems("a", "b", "c"));
  }

  @Test
  public void testAbsoluteValidationNullFirstPath() {
    thrown.expect(NullPointerException.class);
    DisplayData.Path.absolute(null, "foo", "bar");
  }

  @Test
  public void testAbsoluteValidationEmptyFirstPath() {
    thrown.expect(IllegalArgumentException.class);
    DisplayData.Path.absolute("", "foo", "bar");
  }

  @Test
  public void testAbsoluteValidationNullSubsequentPath() {
    thrown.expect(NullPointerException.class);
    DisplayData.Path.absolute("a", "b", null, "c");
  }

  @Test
  public void testAbsoluteValidationEmptySubsequentPath() {
    thrown.expect(IllegalArgumentException.class);
    DisplayData.Path.absolute("a", "b", "", "c");
  }

  @Test
  public void testPathToString() {
    assertEquals("root string", "[]", DisplayData.Path.root().toString());
    assertEquals("single component", "[a]", DisplayData.Path.absolute("a").toString());
    assertEquals("hierarchy", "[a/b/c]", DisplayData.Path.absolute("a", "b", "c").toString());
  }

  @Test
  public void testPathEquality() {
    new EqualsTester()
        .addEqualityGroup(DisplayData.Path.root(), DisplayData.Path.root())
        .addEqualityGroup(DisplayData.Path.root().extend("a"), DisplayData.Path.absolute("a"))
        .addEqualityGroup(
            DisplayData.Path.root().extend("a").extend("b"), DisplayData.Path.absolute("a", "b"))
        .testEquals();
  }

  @Test
  public void testIncludes() {
    final HasDisplayData subComponent =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(DisplayData.Builder builder) {
            builder.add(DisplayData.item("foo", "bar"));
          }
        };

    DisplayData data =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(DisplayData.Builder builder) {
                builder.include("p", subComponent);
              }
            });

    assertThat(data, includesDisplayDataFor("p", subComponent));
  }

  @Test
  public void testIncludeSameComponentAtDifferentPaths() {
    final HasDisplayData subComponent1 =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.add(DisplayData.item("foo", "bar"));
          }
        };
    final HasDisplayData subComponent2 =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.add(DisplayData.item("foo2", "bar2"));
          }
        };

    HasDisplayData component =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.include("p1", subComponent1).include("p2", subComponent2);
          }
        };

    DisplayData data = DisplayData.from(component);
    assertThat(data, includesDisplayDataFor("p1", subComponent1));
    assertThat(data, includesDisplayDataFor("p2", subComponent2));
  }

  @Test
  public void testIncludesComponentsAtSamePath() {
    HasDisplayData component =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.include("p", new NoopDisplayData()).include("p", new NoopDisplayData());
          }
        };

    thrown.expectCause(isA(IllegalArgumentException.class));
    DisplayData.from(component);
  }

  @Test
  public void testNullNamespaceOverride() {
    thrown.expectCause(isA(NullPointerException.class));

    DisplayData.from(
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.add(DisplayData.item("foo", "bar").withNamespace(null));
          }
        });
  }

  @Test
  public void testIdentifierEquality() {
    new EqualsTester()
        .addEqualityGroup(
            DisplayData.Identifier.of(DisplayData.Path.absolute("a"), DisplayDataTest.class, "1"),
            DisplayData.Identifier.of(DisplayData.Path.absolute("a"), DisplayDataTest.class, "1"))
        .addEqualityGroup(
            DisplayData.Identifier.of(DisplayData.Path.absolute("b"), DisplayDataTest.class, "1"))
        .addEqualityGroup(
            DisplayData.Identifier.of(DisplayData.Path.absolute("a"), Object.class, "1"))
        .addEqualityGroup(
            DisplayData.Identifier.of(DisplayData.Path.absolute("a"), DisplayDataTest.class, "2"))
        .testEquals();
  }

  @Test
  public void testItemEquality() {
    new EqualsTester()
        .addEqualityGroup(DisplayData.item("foo", "bar"), DisplayData.item("foo", "bar"))
        .addEqualityGroup(DisplayData.item("foo", "barz"))
        .testEquals();
  }

  @Test
  public void testDisplayDataEquality() {
    HasDisplayData component1 =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.add(DisplayData.item("foo", "bar"));
          }
        };
    HasDisplayData component2 =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.add(DisplayData.item("foo", "bar"));
          }
        };

    DisplayData component1DisplayData1 = DisplayData.from(component1);
    DisplayData component1DisplayData2 = DisplayData.from(component1);
    DisplayData component2DisplayData = DisplayData.from(component2);

    new EqualsTester()
        .addEqualityGroup(component1DisplayData1, component1DisplayData2)
        .addEqualityGroup(component2DisplayData)
        .testEquals();
  }

  @Test
  public void testAcceptsKeysWithDifferentNamespaces() {
    DisplayData data =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(DisplayData.Builder builder) {
                builder
                    .add(DisplayData.item("foo", "bar"))
                    .include(
                        "p",
                        new HasDisplayData() {
                          @Override
                          public void populateDisplayData(DisplayData.Builder builder) {
                            builder.add(DisplayData.item("foo", "bar"));
                          }
                        });
              }
            });

    assertThat(data.items(), hasSize(2));
  }

  @Test
  public void testDuplicateKeyThrowsException() {
    thrown.expectCause(isA(IllegalArgumentException.class));
    DisplayData.from(
        new HasDisplayData() {
          @Override
          public void populateDisplayData(DisplayData.Builder builder) {
            builder.add(DisplayData.item("foo", "bar")).add(DisplayData.item("foo", "baz"));
          }
        });
  }

  @Test
  public void testDuplicateKeyWithNamespaceOverrideDoesntThrow() {
    DisplayData displayData =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(DisplayData.Builder builder) {
                builder
                    .add(DisplayData.item("foo", "bar"))
                    .add(DisplayData.item("foo", "baz").withNamespace(DisplayDataTest.class));
              }
            });

    assertThat(displayData.items(), hasSize(2));
  }

  @Test
  public void testToString() {
    HasDisplayData component =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(DisplayData.Builder builder) {
            builder.add(DisplayData.item("foo", "bar"));
          }
        };

    DisplayData data = DisplayData.from(component);
    assertEquals(String.format("[]%s:foo=bar", component.getClass().getName()), data.toString());
  }

  @Test
  public void testHandlesIncludeCycles() {

    final IncludeSubComponent componentA =
        new IncludeSubComponent() {
          @Override
          String getId() {
            return "componentA";
          }
        };
    final IncludeSubComponent componentB =
        new IncludeSubComponent() {
          @Override
          String getId() {
            return "componentB";
          }
        };

    HasDisplayData component =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.include("p", componentA);
          }
        };

    componentA.subComponent = componentB;
    componentB.subComponent = componentA;

    DisplayData data = DisplayData.from(component);
    assertThat(data.items(), hasSize(2));
  }

  @Test
  public void testHandlesIncludeCyclesDifferentInstances() {
    HasDisplayData component =
        new DelegatingDisplayData(new DelegatingDisplayData(new NoopDisplayData()));

    DisplayData data = DisplayData.from(component);
    assertThat(data.items(), hasSize(2));
  }

  private static class DelegatingDisplayData implements HasDisplayData {
    private final HasDisplayData subComponent;

    public DelegatingDisplayData(HasDisplayData subComponent) {
      this.subComponent = subComponent;
    }

    @Override
    public void populateDisplayData(Builder builder) {
      builder
          .add(DisplayData.item("subComponent", subComponent.getClass()))
          .include("p", subComponent);
    }
  }

  @Test
  public void testIncludesSubcomponentsWithObjectEquality() {
    DisplayData data =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(DisplayData.Builder builder) {
                builder
                    .include("p1", new EqualsEverything("foo1", "bar1"))
                    .include("p2", new EqualsEverything("foo2", "bar2"));
              }
            });

    assertThat(data.items(), hasSize(2));
  }

  private static class EqualsEverything implements HasDisplayData {
    private final String value;
    private final String key;

    EqualsEverything(String key, String value) {
      this.key = key;
      this.value = value;
    }

    @Override
    public void populateDisplayData(DisplayData.Builder builder) {
      builder.add(DisplayData.item(key, value));
    }

    @Override
    public int hashCode() {
      return 1;
    }

    @Override
    @SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
    public boolean equals(Object obj) {
      return true;
    }
  }

  @Test
  public void testDelegate() {
    final HasDisplayData subcomponent =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.add(DisplayData.item("subCompKey", "foo"));
          }
        };

    final HasDisplayData wrapped =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.add(DisplayData.item("wrappedKey", "bar")).include("p", subcomponent);
          }
        };

    HasDisplayData wrapper =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.delegate(wrapped);
          }
        };

    DisplayData data = DisplayData.from(wrapper);
    assertThat(
        data,
        hasDisplayItem(
            allOf(hasKey("wrappedKey"), hasNamespace(wrapped.getClass()), hasPath(/* root */ ))));
    assertThat(
        data,
        hasDisplayItem(
            allOf(hasKey("subCompKey"), hasNamespace(subcomponent.getClass()), hasPath("p"))));
  }

  abstract static class IncludeSubComponent implements HasDisplayData {
    HasDisplayData subComponent;

    @Override
    public void populateDisplayData(DisplayData.Builder builder) {
      builder.add(DisplayData.item("id", getId())).include(getId(), subComponent);
    }

    abstract String getId();
  }

  @Test
  public void testTypeMappings() {
    DisplayData data =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(DisplayData.Builder builder) {
                builder
                    .add(DisplayData.item("string", "foobar"))
                    .add(DisplayData.item("integer", 123))
                    .add(DisplayData.item("float", 2.34))
                    .add(DisplayData.item("boolean", true))
                    .add(DisplayData.item("java_class", DisplayDataTest.class))
                    .add(DisplayData.item("timestamp", Instant.now()))
                    .add(DisplayData.item("duration", Duration.standardHours(1)));
              }
            });

    Collection<Item> items = data.items();
    assertThat(items, hasItem(allOf(hasKey("string"), hasType(DisplayData.Type.STRING))));
    assertThat(items, hasItem(allOf(hasKey("integer"), hasType(DisplayData.Type.INTEGER))));
    assertThat(items, hasItem(allOf(hasKey("float"), hasType(DisplayData.Type.FLOAT))));
    assertThat(items, hasItem(allOf(hasKey("boolean"), hasType(DisplayData.Type.BOOLEAN))));
    assertThat(items, hasItem(allOf(hasKey("java_class"), hasType(DisplayData.Type.JAVA_CLASS))));
    assertThat(items, hasItem(allOf(hasKey("timestamp"), hasType(DisplayData.Type.TIMESTAMP))));
    assertThat(items, hasItem(allOf(hasKey("duration"), hasType(DisplayData.Type.DURATION))));
  }

  @Test
  public void testExplicitItemType() {
    DisplayData data =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(Builder builder) {
                builder
                    .add(DisplayData.item("integer", DisplayData.Type.INTEGER, 1234L))
                    .add(DisplayData.item("string", DisplayData.Type.STRING, "foobar"));
              }
            });

    assertThat(data, hasDisplayItem("integer", 1234L));
    assertThat(data, hasDisplayItem("string", "foobar"));
  }

  @Test
  public void testFormatIncompatibleTypes() {
    Map<DisplayData.Type, Object> invalidPairs =
        ImmutableMap.<DisplayData.Type, Object>builder()
            .put(DisplayData.Type.STRING, 1234)
            .put(DisplayData.Type.INTEGER, "string value")
            .put(DisplayData.Type.FLOAT, "string value")
            .put(DisplayData.Type.BOOLEAN, "string value")
            .put(DisplayData.Type.TIMESTAMP, "string value")
            .put(DisplayData.Type.DURATION, "string value")
            .put(DisplayData.Type.JAVA_CLASS, "string value")
            .build();

    for (Map.Entry<DisplayData.Type, Object> pair : invalidPairs.entrySet()) {
      try {
        DisplayData.Type type = pair.getKey();
        Object invalidValue = pair.getValue();

        type.format(invalidValue);
        fail(
            String.format(
                "Expected exception not thrown for invalid %s value: %s", type, invalidValue));
      } catch (ClassCastException e) {
        // Expected
      }
    }
  }

  @Test
  public void testFormatCompatibleTypes() {
    Multimap<DisplayData.Type, Object> validPairs =
        ImmutableMultimap.<DisplayData.Type, Object>builder()
            .put(DisplayData.Type.INTEGER, 1234)
            .put(DisplayData.Type.INTEGER, 1234L)
            .put(DisplayData.Type.FLOAT, 123.4f)
            .put(DisplayData.Type.FLOAT, 123.4)
            .put(DisplayData.Type.FLOAT, 1234)
            .put(DisplayData.Type.FLOAT, 1234L)
            .build();

    for (Map.Entry<DisplayData.Type, Object> pair : validPairs.entries()) {
      DisplayData.Type type = pair.getKey();
      Object value = pair.getValue();

      try {
        type.format(value);
      } catch (ClassCastException e) {
        throw new AssertionError(
            String.format(
                "Failed to format %s for DisplayData.%s", value.getClass().getSimpleName(), type),
            e);
      }
    }
  }

  @Test
  public void testInvalidExplicitItemType() {
    HasDisplayData component =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.add(DisplayData.item("integer", DisplayData.Type.INTEGER, "foobar"));
          }
        };

    thrown.expectCause(isA(ClassCastException.class));
    DisplayData.from(component);
  }

  @Test
  public void testKnownTypeInference() {
    assertEquals(DisplayData.Type.INTEGER, DisplayData.inferType(1234));
    assertEquals(DisplayData.Type.INTEGER, DisplayData.inferType(1234L));
    assertEquals(DisplayData.Type.FLOAT, DisplayData.inferType(12.3));
    assertEquals(DisplayData.Type.FLOAT, DisplayData.inferType(12.3f));
    assertEquals(DisplayData.Type.BOOLEAN, DisplayData.inferType(true));
    assertEquals(DisplayData.Type.TIMESTAMP, DisplayData.inferType(Instant.now()));
    assertEquals(DisplayData.Type.DURATION, DisplayData.inferType(Duration.millis(1234)));
    assertEquals(DisplayData.Type.JAVA_CLASS, DisplayData.inferType(DisplayDataTest.class));
    assertEquals(DisplayData.Type.STRING, DisplayData.inferType("hello world"));

    assertEquals(null, DisplayData.inferType(null));
    assertEquals(null, DisplayData.inferType(new Object() {}));
  }

  @Test
  public void testStringFormatting() throws IOException {
    final Instant now = Instant.now();
    final Duration oneHour = Duration.standardHours(1);

    HasDisplayData component =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(DisplayData.Builder builder) {
            builder
                .add(DisplayData.item("string", "foobar"))
                .add(DisplayData.item("integer", 123))
                .add(DisplayData.item("float", 2.34))
                .add(DisplayData.item("boolean", true))
                .add(DisplayData.item("java_class", DisplayDataTest.class))
                .add(DisplayData.item("timestamp", now))
                .add(DisplayData.item("duration", oneHour));
          }
        };
    DisplayData data = DisplayData.from(component);

    assertThat(data, hasDisplayItem("string", "foobar"));
    assertThat(data, hasDisplayItem("integer", 123));
    assertThat(data, hasDisplayItem("float", 2.34));
    assertThat(data, hasDisplayItem("boolean", true));
    assertThat(data, hasDisplayItem("java_class", DisplayDataTest.class));
    assertThat(data, hasDisplayItem("timestamp", now));
    assertThat(data, hasDisplayItem("duration", oneHour));
  }

  @Test
  public void testContextProperlyReset() {
    final HasDisplayData subComponent =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(DisplayData.Builder builder) {
            builder.add(DisplayData.item("foo", "bar"));
          }
        };

    HasDisplayData component =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(DisplayData.Builder builder) {
            builder.include("p", subComponent).add(DisplayData.item("alpha", "bravo"));
          }
        };

    DisplayData data = DisplayData.from(component);
    assertThat(data.items(), hasItem(allOf(hasKey("alpha"), hasNamespace(component.getClass()))));
  }

  @Test
  public void testFromNull() {
    thrown.expect(NullPointerException.class);
    DisplayData.from(null);
  }

  @Test
  public void testIncludeNull() {
    thrown.expectCause(isA(NullPointerException.class));
    DisplayData.from(
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.include("p", null);
          }
        });
  }

  @Test
  public void testIncludeNullPath() {
    thrown.expectCause(isA(NullPointerException.class));
    DisplayData.from(
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.include(null, new NoopDisplayData());
          }
        });
  }

  @Test
  public void testIncludeEmptyPath() {
    thrown.expectCause(isA(IllegalArgumentException.class));
    DisplayData.from(
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.include("", new NoopDisplayData());
          }
        });
  }

  @Test
  public void testNullKey() {
    thrown.expectCause(isA(NullPointerException.class));
    DisplayData.from(
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.add(DisplayData.item(null, "foo"));
          }
        });
  }

  @Test
  public void testRejectsNullValues() {
    DisplayData.from(
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            try {
              builder.add(DisplayData.item("key", (String) null));
              throw new RuntimeException("Should throw on null string value");
            } catch (NullPointerException ex) {
              // Expected
            }

            try {
              builder.add(DisplayData.item("key", (Class<?>) null));
              throw new RuntimeException("Should throw on null class value");
            } catch (NullPointerException ex) {
              // Expected
            }

            try {
              builder.add(DisplayData.item("key", (Duration) null));
              throw new RuntimeException("Should throw on null duration value");
            } catch (NullPointerException ex) {
              // Expected
            }

            try {
              builder.add(DisplayData.item("key", (Instant) null));
              throw new RuntimeException("Should throw on null instant value");
            } catch (NullPointerException ex) {
              // Expected
            }
          }
        });
  }

  @Test
  public void testAcceptsNullOptionalValues() {
    DisplayData.from(
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.add(DisplayData.item("key", "value").withLabel(null).withLinkUrl(null));
          }
        });

    // Should not throw
  }

  @Test
  public void testJsonSerialization() throws IOException {
    final String stringValue = "foobar";
    final int intValue = 1234;
    final double floatValue = 123.4;
    final boolean boolValue = true;
    final int durationMillis = 1234;

    HasDisplayData component =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder
                .add(DisplayData.item("string", stringValue))
                .add(DisplayData.item("long", intValue))
                .add(DisplayData.item("double", floatValue))
                .add(DisplayData.item("boolean", boolValue))
                .add(DisplayData.item("instant", new Instant(0)))
                .add(DisplayData.item("duration", Duration.millis(durationMillis)))
                .add(
                    DisplayData.item("class", DisplayDataTest.class)
                        .withLinkUrl("http://abc")
                        .withLabel("baz"));
          }
        };
    DisplayData data = DisplayData.from(component);

    JsonNode json = MAPPER.readTree(MAPPER.writeValueAsBytes(data));
    assertThat(json, hasExpectedJson(component, "STRING", "string", quoted(stringValue)));
    assertThat(json, hasExpectedJson(component, "INTEGER", "long", intValue));
    assertThat(json, hasExpectedJson(component, "FLOAT", "double", floatValue));
    assertThat(json, hasExpectedJson(component, "BOOLEAN", "boolean", boolValue));
    assertThat(json, hasExpectedJson(component, "DURATION", "duration", durationMillis));
    assertThat(
        json,
        hasExpectedJson(component, "TIMESTAMP", "instant", quoted("1970-01-01T00:00:00.000Z")));
    assertThat(
        json,
        hasExpectedJson(
            component,
            "JAVA_CLASS",
            "class",
            quoted(DisplayDataTest.class.getName()),
            quoted("DisplayDataTest"),
            "baz",
            "http://abc"));
  }

  @Test
  public void testJsonSerializationAnonymousClassNamespace() throws IOException {
    HasDisplayData component =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.add(DisplayData.item("foo", "bar"));
          }
        };
    DisplayData data = DisplayData.from(component);

    JsonNode json = MAPPER.readTree(MAPPER.writeValueAsBytes(data));
    String namespace = json.elements().next().get("namespace").asText();
    final Pattern anonClassRegex =
        Pattern.compile(Pattern.quote(DisplayDataTest.class.getName()) + "\\$\\d+$");
    assertThat(
        namespace,
        new CustomTypeSafeMatcher<String>("anonymous class regex: " + anonClassRegex) {
          @Override
          protected boolean matchesSafely(String item) {
            java.util.regex.Matcher m = anonClassRegex.matcher(item);
            return m.matches();
          }
        });
  }

  @Test
  public void testCanSerializeItemSpecReference() {
    DisplayData.ItemSpec<?> spec = DisplayData.item("clazz", DisplayDataTest.class);
    SerializableUtils.ensureSerializable(new HoldsItemSpecReference(spec));
  }

  private static class HoldsItemSpecReference implements Serializable {
    private final DisplayData.ItemSpec<?> spec;

    public HoldsItemSpecReference(DisplayData.ItemSpec<?> spec) {
      this.spec = spec;
    }
  }

  @Test
  public void testSerializable() {
    DisplayData data =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(DisplayData.Builder builder) {
                builder.add(DisplayData.item("foo", "bar"));
              }
            });

    DisplayData serData = SerializableUtils.clone(data);
    assertEquals(data, serData);
  }

  /**
   * Verify that {@link DisplayData.Builder} can recover from exceptions thrown in user code. This
   * is not used within the Beam SDK since we want all code to produce valid DisplayData. This test
   * just ensures it is possible to write custom code that does recover.
   */
  @Test
  public void testCanRecoverFromBuildException() {
    final HasDisplayData safeComponent =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.add(DisplayData.item("a", "a"));
          }
        };

    final HasDisplayData failingComponent =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            throw new RuntimeException("oh noes!");
          }
        };

    DisplayData displayData =
        DisplayData.from(
            new HasDisplayData() {
              @Override
              public void populateDisplayData(Builder builder) {
                builder.add(DisplayData.item("b", "b")).add(DisplayData.item("c", "c"));

                try {
                  builder.include("p", failingComponent);
                  fail("Expected exception not thrown");
                } catch (RuntimeException e) {
                  // Expected
                }

                builder.include("p", safeComponent).add(DisplayData.item("d", "d"));
              }
            });

    assertThat(displayData, hasDisplayItem("a"));
    assertThat(displayData, hasDisplayItem("b"));
    assertThat(displayData, hasDisplayItem("c"));
    assertThat(displayData, hasDisplayItem("d"));
  }

  @Test
  public void testExceptionMessage() {
    final RuntimeException cause = new RuntimeException("oh noes!");
    HasDisplayData component =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            throw cause;
          }
        };

    thrown.expectMessage(component.getClass().getName());
    thrown.expectCause(is(cause));

    DisplayData.from(component);
  }

  @Test
  public void testExceptionsNotWrappedRecursively() {
    final RuntimeException cause = new RuntimeException("oh noes!");
    HasDisplayData component =
        new HasDisplayData() {
          @Override
          public void populateDisplayData(Builder builder) {
            builder.include(
                "p",
                new HasDisplayData() {
                  @Override
                  public void populateDisplayData(Builder builder) {
                    throw cause;
                  }
                });
          }
        };

    thrown.expectCause(is(cause));
    DisplayData.from(component);
  }

  @AutoValue
  abstract static class Foo implements HasDisplayData {
    @Override
    public void populateDisplayData(Builder builder) {
      builder.add(DisplayData.item("someKey", "someValue"));
    }
  }

  @Test
  public void testAutoValue() {
    DisplayData data = DisplayData.from(new AutoValue_DisplayDataTest_Foo());
    Item item = Iterables.getOnlyElement(data.asMap().values());
    assertEquals(Foo.class, item.getNamespace());
  }

  private String quoted(Object obj) {
    return String.format("\"%s\"", obj);
  }

  private Matcher<Iterable<? super JsonNode>> hasExpectedJson(
      HasDisplayData component, String type, String key, Object value) throws IOException {
    return hasExpectedJson(component, type, key, value, null, null, null);
  }

  private Matcher<Iterable<? super JsonNode>> hasExpectedJson(
      HasDisplayData component,
      String type,
      String key,
      Object value,
      Object shortValue,
      String label,
      String linkUrl)
      throws IOException {
    Class<?> nsClass = component.getClass();

    StringBuilder builder = new StringBuilder();
    builder.append("{");
    builder.append(String.format("\"namespace\":\"%s\",", nsClass.getName()));
    builder.append(String.format("\"type\":\"%s\",", type));
    builder.append(String.format("\"key\":\"%s\",", key));
    builder.append(String.format("\"value\":%s", value));

    if (shortValue != null) {
      builder.append(String.format(",\"shortValue\":%s", shortValue));
    }
    if (label != null) {
      builder.append(String.format(",\"label\":\"%s\"", label));
    }
    if (linkUrl != null) {
      builder.append(String.format(",\"linkUrl\":\"%s\"", linkUrl));
    }

    builder.append("}");

    JsonNode jsonNode = MAPPER.readTree(builder.toString());
    return hasItem(jsonNode);
  }

  private static class NoopDisplayData implements HasDisplayData {
    @Override
    public void populateDisplayData(Builder builder) {}
  }

  private static Matcher<DisplayData.Item> hasUrl(Matcher<String> urlMatcher) {
    return new FeatureMatcher<DisplayData.Item, String>(
        urlMatcher, "display item with url", "URL") {
      @Override
      protected String featureValueOf(DisplayData.Item actual) {
        return actual.getLinkUrl();
      }
    };
  }

  private static <T> Matcher<DisplayData.Item> hasShortValue(Matcher<T> valueStringMatcher) {
    return new FeatureMatcher<DisplayData.Item, T>(
        valueStringMatcher, "display item with short value", "short value") {
      @Override
      protected T featureValueOf(DisplayData.Item actual) {
        @SuppressWarnings("unchecked")
        T shortValue = (T) actual.getShortValue();
        return shortValue;
      }
    };
  }
}
