// 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 == NestedSet.EMPTY_CHILDREN) {
      assertThat(rhs).isSameInstanceAs(NestedSet.EMPTY_CHILDREN);
    } else 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]);
      }
    } else {
      assertThat(lhs).isEqualTo(rhs);
    }
  }
}
