/*
 * 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.io.fs;

import static org.apache.beam.sdk.io.fs.ResolveOptions.StandardResolveOptions.RESOLVE_DIRECTORY;
import static org.apache.beam.sdk.io.fs.ResolveOptions.StandardResolveOptions.RESOLVE_FILE;
import static org.apache.beam.vendor.guava.v20_0.com.google.common.base.Preconditions.checkArgument;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.fail;

import com.google.common.testing.EqualsTester;
import java.util.ArrayList;
import java.util.List;
import org.apache.beam.sdk.annotations.Experimental;
import org.apache.beam.sdk.annotations.Experimental.Kind;
import org.apache.beam.sdk.io.FileSystems;

/** A utility to test {@link ResourceId} implementations. */
@Experimental(Kind.FILESYSTEM)
public final class ResourceIdTester {
  /**
   * Enforces that the {@link ResourceId} implementation of {@code baseDirectory} meets the {@link
   * ResourceId} spec.
   */
  public static void runResourceIdBattery(ResourceId baseDirectory) {
    checkArgument(
        baseDirectory.isDirectory(), "baseDirectory %s is not a directory", baseDirectory);

    List<ResourceId> allResourceIds = new ArrayList<>();
    allResourceIds.add(baseDirectory);

    // Validate that individual resources meet the fairly restrictive spec we have.
    validateResourceIds(allResourceIds);

    // Validate operations with resolving child resources.
    validateResolvingIds(baseDirectory, allResourceIds);

    // Validate safeguards against resolving bad paths.
    validateFailureResolvingIds(baseDirectory);
  }

  private static void validateResolvingIds(
      ResourceId baseDirectory, List<ResourceId> allResourceIds) {
    ResourceId file1 = baseDirectory.resolve("child1", RESOLVE_FILE);
    ResourceId file2 = baseDirectory.resolve("child2", RESOLVE_FILE);
    ResourceId file2a = baseDirectory.resolve("child2", RESOLVE_FILE);
    allResourceIds.add(file1);
    allResourceIds.add(file2);
    assertThat("Resolved file isDirectory()", file1.isDirectory(), is(false));
    assertThat("Resolved file isDirectory()", file2.isDirectory(), is(false));
    assertThat("Resolved file isDirectory()", file2a.isDirectory(), is(false));

    ResourceId dir1 = baseDirectory.resolve("child1", RESOLVE_DIRECTORY);
    ResourceId dir2 = baseDirectory.resolve("child2", RESOLVE_DIRECTORY);
    ResourceId dir2a = baseDirectory.resolve("child2", RESOLVE_DIRECTORY);
    assertThat("Resolved directory isDirectory()", dir1.isDirectory(), is(true));
    assertThat("Resolved directory isDirectory()", dir2.isDirectory(), is(true));
    assertThat("Resolved directory isDirectory()", dir2a.isDirectory(), is(true));
    allResourceIds.add(dir1);
    allResourceIds.add(dir2);

    // ResourceIds in equality groups.
    new EqualsTester()
        .addEqualityGroup(file1)
        .addEqualityGroup(file2, file2a)
        .addEqualityGroup(dir1, dir1.getCurrentDirectory())
        .addEqualityGroup(dir2, dir2a, dir2.getCurrentDirectory())
        .addEqualityGroup(baseDirectory, file1.getCurrentDirectory(), file2.getCurrentDirectory())
        .testEquals();

    // ResourceId toString() in equality groups.
    new EqualsTester()
        .addEqualityGroup(file1.toString())
        .addEqualityGroup(file2.toString(), file2a.toString())
        .addEqualityGroup(dir1.toString(), dir1.getCurrentDirectory().toString())
        .addEqualityGroup(dir2.toString(), dir2a.toString(), dir2.getCurrentDirectory().toString())
        .addEqualityGroup(
            baseDirectory.toString(),
            file1.getCurrentDirectory().toString(),
            file2.getCurrentDirectory().toString())
        .testEquals();

    // TODO: test resolving strings that need to be escaped.
    //   Possible spec: https://tools.ietf.org/html/rfc3986#section-2
    //   May need options to be filesystem-independent, e.g., if filesystems ban certain chars.
  }

  private static void validateFailureResolvingIds(ResourceId baseDirectory) {
    try {
      ResourceId badFile = baseDirectory.resolve("file/", RESOLVE_FILE);
      fail(String.format("Resolving badFile %s should have failed", badFile));
    } catch (IllegalArgumentException e) {
      // expected
    }

    ResourceId file = baseDirectory.resolve("file", RESOLVE_FILE);
    try {
      file.resolve("file2", RESOLVE_FILE);
      fail(String.format("Should not be able to resolve against file resource %s", file));
    } catch (IllegalStateException e) {
      // expected
    }
  }

  private static void validateResourceIds(List<ResourceId> resourceIds) {
    for (ResourceId resourceId : resourceIds) {
      // ResourceIds should equal themselves.
      assertThat("ResourceId equal to itself", resourceId, equalTo(resourceId));

      // ResourceIds should be clonable via FileSystems#matchNewResource.
      ResourceId cloned;
      if (resourceId.isDirectory()) {
        cloned = FileSystems.matchNewResource(resourceId.toString(), true /* isDirectory */);
      } else {
        cloned = FileSystems.matchNewResource(resourceId.toString(), false /* isDirectory */);
      }
      assertThat("ResourceId equals clone of itself", cloned, equalTo(resourceId));
      // .. and clones have consistent toString.
      assertThat(
          "ResourceId toString consistency", cloned.toString(), equalTo(resourceId.toString()));
      // .. and have consistent isDirectory.
      assertThat(
          "ResourceId isDirectory consistency",
          cloned.isDirectory(),
          equalTo(resourceId.isDirectory()));
    }
  }

  private ResourceIdTester() {} // prevent instantiation
}
