// Copyright 2018 The Bazel Authors. All rights reserved.
//
// 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.google.devtools.build.lib.skyframe.serialization;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;

import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationTester;
import java.io.BufferedInputStream;
import java.util.Arrays;
import java.util.Objects;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link DynamicCodec}. */
@RunWith(JUnit4.class)
public final class DynamicCodecTest {

  private static class SimpleExample {
    private final String elt;
    private final String elt2;
    private final int x;

    private SimpleExample(String elt, String elt2, int x) {
      this.elt = elt;
      this.elt2 = elt2;
      this.x = x;
    }

    @SuppressWarnings("EqualsHashCode") // Testing
    @Override
    public boolean equals(Object other) {
      if (!(other instanceof SimpleExample)) {
        return false;
      }
      SimpleExample that = (SimpleExample) other;
      return Objects.equals(elt, that.elt) && Objects.equals(elt2, that.elt2) && x == that.x;
    }
  }

  @Test
  public void testExample() throws Exception {
    new SerializationTester(new SimpleExample("a", "b", -5), new SimpleExample("a", null, 10))
        .addCodec(new DynamicCodec(SimpleExample.class))
        .makeMemoizing()
        .runTests();
  }

  private static class ExampleSubclass extends SimpleExample {
    private final String elt; // duplicate name with superclass

    private ExampleSubclass(String elt1, String elt2, String elt3, int x) {
      super(elt1, elt2, x);
      this.elt = elt3;
    }

    @SuppressWarnings("EqualsHashCode") // Testing
    @Override
    public boolean equals(Object other) {
      if (!(other instanceof ExampleSubclass)) {
        return false;
      }
      if (!super.equals(other)) {
        return false;
      }
      ExampleSubclass that = (ExampleSubclass) other;
      return Objects.equals(elt, that.elt);
    }
  }

  @Test
  public void testExampleSubclass() throws Exception {
    new SerializationTester(
            new ExampleSubclass("a", "b", "c", 0), new ExampleSubclass("a", null, null, 15))
        .addCodec(new DynamicCodec(ExampleSubclass.class))
        .makeMemoizing()
        .runTests();
  }

  private static class ExampleSmallPrimitives {
    private final Void v;
    private final boolean bit;
    private final byte b;
    private final short s;
    private final char c;

    private ExampleSmallPrimitives(boolean bit, byte b, short s, char c) {
      this.v = null;
      this.bit = bit;
      this.b = b;
      this.s = s;
      this.c = c;
    }

    @SuppressWarnings("EqualsHashCode") // Testing
    @Override
    public boolean equals(Object other) {
      if (!(other instanceof ExampleSmallPrimitives)) {
        return false;
      }
      ExampleSmallPrimitives that = (ExampleSmallPrimitives) other;
      return v == that.v && bit == that.bit && b == that.b && s == that.s && c == that.c;
    }
  }

  @Test
  public void testExampleSmallPrimitives() throws Exception {
    new SerializationTester(
            new ExampleSmallPrimitives(false, (byte) 0, (short) 0, 'a'),
            new ExampleSmallPrimitives(false, (byte) 120, (short) 18000, 'x'),
            new ExampleSmallPrimitives(true, Byte.MIN_VALUE, Short.MIN_VALUE, Character.MIN_VALUE),
            new ExampleSmallPrimitives(true, Byte.MAX_VALUE, Short.MAX_VALUE, Character.MAX_VALUE))
        .addCodec(new DynamicCodec(ExampleSmallPrimitives.class))
        .makeMemoizing()
        .runTests();
  }

  private static class ExampleMediumPrimitives {
    private final int i;
    private final float f;

    private ExampleMediumPrimitives(int i, float f) {
      this.i = i;
      this.f = f;
    }

    @SuppressWarnings("EqualsHashCode") // Testing
    @Override
    public boolean equals(Object other) {
      if (!(other instanceof ExampleMediumPrimitives)) {
        return false;
      }
      ExampleMediumPrimitives that = (ExampleMediumPrimitives) other;
      return i == that.i && f == that.f;
    }
  }

  @Test
  public void testExampleMediumPrimitives() throws Exception {
    new SerializationTester(
            new ExampleMediumPrimitives(12345, 1e12f),
            new ExampleMediumPrimitives(67890, -6e9f),
            new ExampleMediumPrimitives(Integer.MIN_VALUE, Float.MIN_VALUE),
            new ExampleMediumPrimitives(Integer.MAX_VALUE, Float.MAX_VALUE))
        .addCodec(new DynamicCodec(ExampleMediumPrimitives.class))
        .makeMemoizing()
        .runTests();
  }

  private static class ExampleLargePrimitives {
    private final long l;
    private final double d;

    private ExampleLargePrimitives(long l, double d) {
      this.l = l;
      this.d = d;
    }

    @SuppressWarnings("EqualsHashCode") // Testing
    @Override
    public boolean equals(Object other) {
      if (!(other instanceof ExampleLargePrimitives)) {
        return false;
      }
      ExampleLargePrimitives that = (ExampleLargePrimitives) other;
      return l == that.l && d == that.d;
    }
  }

  @Test
  public void testExampleLargePrimitives() throws Exception {
    new SerializationTester(
            new ExampleLargePrimitives(12345346523453L, 1e300),
            new ExampleLargePrimitives(678900093045L, -9e180),
            new ExampleLargePrimitives(Long.MIN_VALUE, Double.MIN_VALUE),
            new ExampleLargePrimitives(Long.MAX_VALUE, Double.MAX_VALUE))
        .addCodec(new DynamicCodec(ExampleLargePrimitives.class))
        .makeMemoizing()
        .runTests();
  }

  private static class ArrayExample {
    String[] text;
    byte[] numbers;
    char[] chars;
    long[] longs;

    private ArrayExample(String[] text, byte[] numbers, char[] chars, long[] longs) {
      this.text = text;
      this.numbers = numbers;
      this.chars = chars;
      this.longs = longs;
    }

    @SuppressWarnings("EqualsHashCode") // Testing
    @Override
    public boolean equals(Object other) {
      if (!(other instanceof ArrayExample)) {
        return false;
      }
      ArrayExample that = (ArrayExample) other;
      return Arrays.equals(text, that.text)
          && Arrays.equals(numbers, that.numbers)
          && Arrays.equals(chars, that.chars)
          && Arrays.equals(longs, that.longs);
    }
  }

  @Test
  public void testArray() throws Exception {
    new SerializationTester(
            new ArrayExample(null, null, null, null),
            new ArrayExample(new String[] {}, new byte[] {}, new char[] {}, new long[] {}),
            new ArrayExample(
                new String[] {"a", "b", "cde"},
                new byte[] {-1, 0, 1},
                new char[] {'a', 'b', 'c', 'x', 'y', 'z'},
                new long[] {Long.MAX_VALUE, Long.MIN_VALUE, 27983741982341L, 52893748523495834L}))
        .addCodec(new DynamicCodec(ArrayExample.class))
        .runTests();
  }

  private static class NestedArrayExample {
    int[][] numbers;

    private NestedArrayExample(int[][] numbers) {
      this.numbers = numbers;
    }

    @SuppressWarnings("EqualsHashCode") // Testing
    @Override
    public boolean equals(Object other) {
      if (!(other instanceof NestedArrayExample)) {
        return false;
      }
      NestedArrayExample that = (NestedArrayExample) other;
      return Arrays.deepEquals(numbers, that.numbers);
    }
  }

  @Test
  public void testNestedArray() throws Exception {
    new SerializationTester(
            new NestedArrayExample(null),
            new NestedArrayExample(
                new int[][] {
                  {1, 2, 3},
                  {4, 5, 6, 9},
                  {7}
                }),
            new NestedArrayExample(new int[][] {{1, 2, 3}, null, {7}}))
        .addCodec(new DynamicCodec(NestedArrayExample.class))
        .runTests();
  }

  private static class CycleA {
    private final int value;
    private CycleB b;

    private CycleA(int value) {
      this.value = value;
    }

    @SuppressWarnings("EqualsHashCode") // Testing
    @Override
    public boolean equals(Object other) {
      // Integrity check. Not really part of equals.
      assertThat(b.a).isEqualTo(this);
      if (!(other instanceof CycleA)) {
        return false;
      }
      CycleA that = (CycleA) other;
      // Consistency check. Not really part of equals.
      assertThat(that.b.a).isEqualTo(that);
      return value == that.value && b.value() == that.b.value;
    }
  }

  private static class CycleB {
    private final int value;
    private CycleA a;

    private CycleB(int value) {
      this.value = value;
    }

    public int value() {
      return value;
    }
  }

  private static CycleA createCycle(int valueA, int valueB) {
    CycleA a = new CycleA(valueA);
    a.b = new CycleB(valueB);
    a.b.a = a;
    return a;
  }

  @Test
  public void testCyclic() throws Exception {
    new SerializationTester(createCycle(1, 2), createCycle(3, 4))
        .addCodec(new DynamicCodec(CycleA.class))
        .addCodec(new DynamicCodec(CycleB.class))
        .makeMemoizing()
        .runTests();
  }

  enum EnumExample {
    ZERO,
    ONE,
    TWO,
    THREE
  }

  static class PrimitiveExample {

    private final boolean booleanValue;
    private final int intValue;
    private final double doubleValue;
    private final EnumExample enumValue;
    private final String stringValue;

    PrimitiveExample(
        boolean booleanValue,
        int intValue,
        double doubleValue,
        EnumExample enumValue,
        String stringValue) {
      this.booleanValue = booleanValue;
      this.intValue = intValue;
      this.doubleValue = doubleValue;
      this.enumValue = enumValue;
      this.stringValue = stringValue;
    }

    @SuppressWarnings("EqualsHashCode") // Testing
    @Override
    public boolean equals(Object object) {
      if (object == null) {
        return false;
      }
      PrimitiveExample that = (PrimitiveExample) object;
      return booleanValue == that.booleanValue
          && intValue == that.intValue
          && doubleValue == that.doubleValue
          && Objects.equals(enumValue, that.enumValue)
          && Objects.equals(stringValue, that.stringValue);
    }
  }

  @Test
  public void testPrimitiveExample() throws Exception {
    new SerializationTester(
            new PrimitiveExample(true, 1, 1.1, EnumExample.ZERO, "foo"),
            new PrimitiveExample(false, -1, -5.5, EnumExample.ONE, "bar"),
            new PrimitiveExample(true, 5, 20.0, EnumExample.THREE, null),
            new PrimitiveExample(true, 100, 100, null, "hello"))
        .addCodec(new DynamicCodec(PrimitiveExample.class))
        .addCodec(new EnumCodec<>(EnumExample.class))
        .setRepetitions(100000)
        .runTests();
  }

  private static class NoCodecExample2 {
    @SuppressWarnings("unused")
    private final BufferedInputStream noCodec = new BufferedInputStream(null);
  }

  private static class NoCodecExample1 {
    @SuppressWarnings("unused")
    private final NoCodecExample2 noCodec = new NoCodecExample2();
  }

  @Test
  public void testNoCodecExample() throws Exception {
    ObjectCodecs codecs = new ObjectCodecs(AutoRegistry.get(), ImmutableMap.of());
    SerializationException.NoCodecException expected =
        assertThrows(
            SerializationException.NoCodecException.class,
            () -> codecs.serializeMemoized(new NoCodecExample1()));
    assertThat(expected)
        .hasMessageThat()
        .contains(
            "java.io.BufferedInputStream ["
                + "java.io.BufferedInputStream, "
                + "com.google.devtools.build.lib.skyframe.serialization."
                + "DynamicCodecTest$NoCodecExample2, "
                + "com.google.devtools.build.lib.skyframe.serialization."
                + "DynamicCodecTest$NoCodecExample1]");
  }
}
