/*
 * 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.runners.reference;

import static org.apache.beam.vendor.guava.v20_0.com.google.common.base.Preconditions.checkArgument;
import static org.apache.beam.vendor.guava.v20_0.com.google.common.base.Preconditions.checkState;

import javax.annotation.Nullable;

/**
 * An {@link AutoCloseable} that wraps a resource that needs to be cleaned up but does not implement
 * {@link AutoCloseable} itself.
 *
 * <p>Recipients of a {@link CloseableResource} are in general responsible for cleanup. Ownership
 * can be transferred from one context to another via {@link #transfer()}. Transferring relinquishes
 * ownership from the original resource. This allows resources to be safely constructed and
 * transferred within a try-with-resources block. For example:
 *
 * <p>{@code try (CloseableResource<Foo> resource = CloseableResource.of(...)) { // Do something
 * with resource. ... // Then transfer ownership to some consumer.
 * resourceConsumer(resource.transfer()); } }
 *
 * <p>Not thread-safe.
 */
public class CloseableResource<T> implements AutoCloseable {

  private final T resource;

  /**
   * {@link Closer } for the underlying resource. Closers are nullable to allow transfer of
   * ownership. However, newly-constructed {@link CloseableResource CloseableResources} must always
   * have non-null closers.
   */
  @Nullable private Closer<T> closer;

  private boolean isClosed = false;

  private CloseableResource(T resource, Closer<T> closer) {
    this.resource = resource;
    this.closer = closer;
  }

  /** Creates a {@link CloseableResource} with the given resource and closer. */
  public static <T> CloseableResource<T> of(T resource, Closer<T> closer) {
    checkArgument(resource != null, "Resource must be non-null");
    checkArgument(closer != null, "%s must be non-null", Closer.class.getName());
    return new CloseableResource<>(resource, closer);
  }

  /** Gets the underlying resource. */
  public T get() {
    checkState(closer != null, "%s has transferred ownership", CloseableResource.class.getName());
    checkState(!isClosed, "% is closed", CloseableResource.class.getName());
    return resource;
  }

  /**
   * Returns a new {@link CloseableResource} that owns the underlying resource and relinquishes
   * ownership from this {@link CloseableResource}. {@link #close()} on the original instance
   * becomes a no-op.
   */
  public CloseableResource<T> transfer() {
    checkState(closer != null, "%s has transferred ownership", CloseableResource.class.getName());
    checkState(!isClosed, "% is closed", CloseableResource.class.getName());
    CloseableResource<T> other = CloseableResource.of(resource, closer);
    this.closer = null;
    return other;
  }

  /**
   * Closes the underlying resource. The closer will only be executed on the first call.
   *
   * @throws CloseException wrapping any exceptions thrown while closing
   */
  @Override
  public void close() throws CloseException {
    if (closer != null && !isClosed) {
      try {
        closer.close(resource);
      } catch (Exception e) {
        throw new CloseException(e);
      } finally {
        // Mark resource as closed even if we catch an exception.
        isClosed = true;
      }
    }
  }

  /** A function that knows how to clean up after a resource. */
  @FunctionalInterface
  public interface Closer<T> {
    void close(T resource) throws Exception;
  }

  /** An exception that wraps errors thrown while a resource is being closed. */
  public static class CloseException extends Exception {
    private CloseException(Exception e) {
      super("Error closing resource", e);
    }
  }
}
