// 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.collect.nestedset;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.base.Objects;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.devtools.build.lib.skyframe.serialization.ObjectCodecs;
import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationTester;
import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationTester.VerificationFunction;
import java.io.IOException;

/** Utilities for testing NestedSet serialization. */
public class NestedSetCodecTestUtils {

  private static final NestedSet<String> SHARED_NESTED_SET =
      NestedSetBuilder.<String>stableOrder().add("e").build();

  @AutoCodec
  static class HasNestedSet {
    private final NestedSet<String> nestedSetField;

    @VisibleForSerialization
    HasNestedSet(NestedSet<String> nestedSetField) {
      this.nestedSetField = nestedSetField;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }
      HasNestedSet that = (HasNestedSet) o;
      return Objects.equal(nestedSetField.getChildren(), that.nestedSetField.getChildren());
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(nestedSetField);
    }
  }

  /** Perform serialization/deserialization checks for several simple NestedSet examples. */
  public static void checkCodec(
      ObjectCodecs objectCodecs, boolean allowFutureBlocking, boolean assertSymmetricEquality)
      throws Exception {
    new SerializationTester(
            NestedSetBuilder.emptySet(Order.STABLE_ORDER),
            NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER),
            NestedSetBuilder.create(Order.STABLE_ORDER, "a"),
            NestedSetBuilder.create(Order.STABLE_ORDER, "a", "b", "c"),
            NestedSetBuilder.<String>stableOrder()
                .add("a")
                .add("b")
                .addTransitive(
                    NestedSetBuilder.<String>stableOrder()
                        .add("c")
                        .addTransitive(SHARED_NESTED_SET)
                        .build())
                .addTransitive(
                    NestedSetBuilder.<String>stableOrder()
                        .add("d")
                        .addTransitive(SHARED_NESTED_SET)
                        .build())
                .addTransitive(NestedSetBuilder.emptySet(Order.STABLE_ORDER))
                .build(),
            NestedSetBuilder.create(
                Order.STABLE_ORDER,
                new HasNestedSet(NestedSetBuilder.create(Order.STABLE_ORDER, "a"))))
        .setObjectCodecs(objectCodecs)
        .makeMemoizingAndAllowFutureBlocking(allowFutureBlocking)
        .setVerificationFunction(verificationFunction(assertSymmetricEquality))
        .runTests();
  }

  public static ListenableFuture<Void> writeToStoreFuture(
      NestedSetStore store, NestedSet<?> nestedSet, SerializationContext serializationContext)
      throws IOException, SerializationException {
    return store
        .computeFingerprintAndStore((Object[]) nestedSet.getChildren(), serializationContext)
        .writeStatus();
  }

  private static VerificationFunction<NestedSet<String>> verificationFunction(
      boolean assertSymmetricEquality) {
    return (subject, deserialized) -> {
      if (assertSymmetricEquality) {
        assertThat(deserialized).isEqualTo(subject);
        assertThat(subject).isEqualTo(deserialized);
      }
      assertThat(subject.getOrder()).isEqualTo(deserialized.getOrder());
      assertThat(subject.toSet()).isEqualTo(deserialized.toSet());
      verifyStructure(subject.getChildren(), deserialized.getChildren());
    };
  }

  private static void verifyStructure(Object lhs, Object rhs) {
    if (lhs instanceof Object[]) {
      assertThat(rhs).isInstanceOf(Object[].class);
      Object[] lhsArray = (Object[]) lhs;
      Object[] rhsArray = (Object[]) rhs;
      int n = lhsArray.length;
      assertThat(rhsArray).hasLength(n);
      for (int i = 0; i < n; ++i) {
        verifyStructure(lhsArray[i], rhsArray[i]);
      }
      if (lhsArray.length == 0) {
        // Verify empty-children is optimized - we're not creating multiple empty arrays.
        assertThat(lhsArray).isSameInstanceAs(rhsArray);
      }
    } else {
      assertThat(lhs).isEqualTo(rhs);
    }
  }
}
