// Copyright 2019 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.vfs;

import com.google.common.base.Preconditions;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.ReadableByteChannel;
import java.util.Collection;

/**
 * A file system that delegates all operations to {@code delegateFs} under the hood.
 *
 * <p>This is helpful when wanting to implement a file system on top of another file system as it
 * allows code patterns like: <code>
 * {@literal @}Override
 * protected long getFileSize(Path path, boolean followSymlinks) throws IOException {
 *   if (!someCondition) {
 *     return super.getFileSize(path, followSymlinks);
 *   }
 *   return rpc.getFileSize(path, followSymlinks);
 * }
 * </code>
 */
public abstract class DelegateFileSystem extends FileSystem {

  private final FileSystem delegateFs;

  public DelegateFileSystem(FileSystem delegateFs) {
    super(Preconditions.checkNotNull(delegateFs, "delegateFs").getDigestFunction());
    this.delegateFs = delegateFs;
  }

  @Override
  public boolean supportsModifications(Path path) {
    return delegateFs.supportsModifications(toDelegatePath(path));
  }

  @Override
  public boolean supportsSymbolicLinksNatively(Path path) {
    return delegateFs.supportsSymbolicLinksNatively(toDelegatePath(path));
  }

  @Override
  protected boolean supportsHardLinksNatively(Path path) {
    return delegateFs.supportsHardLinksNatively(toDelegatePath(path));
  }

  @Override
  public boolean isFilePathCaseSensitive() {
    return delegateFs.isFilePathCaseSensitive();
  }

  @Override
  public boolean createDirectory(Path path) throws IOException {
    return delegateFs.createDirectory(toDelegatePath(path));
  }

  @Override
  public void createDirectoryAndParents(Path path) throws IOException {
    delegateFs.createDirectoryAndParents(toDelegatePath(path));
  }

  @Override
  protected long getFileSize(Path path, boolean followSymlinks) throws IOException {
    return delegateFs.getFileSize(toDelegatePath(path), followSymlinks);
  }

  @Override
  public boolean delete(Path path) throws IOException {
    return delegateFs.delete(toDelegatePath(path));
  }

  @Override
  protected long getLastModifiedTime(Path path, boolean followSymlinks) throws IOException {
    return delegateFs.getLastModifiedTime(toDelegatePath(path), followSymlinks);
  }

  @Override
  public void setLastModifiedTime(Path path, long newTime) throws IOException {
    delegateFs.setLastModifiedTime(toDelegatePath(path), newTime);
  }

  @Override
  protected boolean isSymbolicLink(Path path) {
    return delegateFs.isSymbolicLink(toDelegatePath(path));
  }

  @Override
  protected boolean isDirectory(Path path, boolean followSymlinks) {
    return delegateFs.isDirectory(toDelegatePath(path), followSymlinks);
  }

  @Override
  protected boolean isFile(Path path, boolean followSymlinks) {
    return delegateFs.isFile(toDelegatePath(path), followSymlinks);
  }

  @Override
  protected boolean isSpecialFile(Path path, boolean followSymlinks) {
    return delegateFs.isSpecialFile(toDelegatePath(path), followSymlinks);
  }

  @Override
  protected void createSymbolicLink(Path linkPath, PathFragment targetFragment) throws IOException {
    delegateFs.createSymbolicLink(toDelegatePath(linkPath), targetFragment);
  }

  @Override
  protected PathFragment readSymbolicLink(Path path) throws IOException {
    return delegateFs.readSymbolicLink(toDelegatePath(path));
  }

  @Override
  protected boolean exists(Path path, boolean followSymlinks) {
    return delegateFs.exists(toDelegatePath(path), followSymlinks);
  }

  @Override
  public boolean exists(Path path) {
    return delegateFs.exists(toDelegatePath(path));
  }

  @Override
  protected Collection<String> getDirectoryEntries(Path path) throws IOException {
    return delegateFs.getDirectoryEntries(toDelegatePath(path));
  }

  @Override
  protected boolean isReadable(Path path) throws IOException {
    return delegateFs.isReadable(toDelegatePath(path));
  }

  @Override
  protected void setReadable(Path path, boolean readable) throws IOException {
    delegateFs.setReadable(toDelegatePath(path), readable);
  }

  @Override
  protected boolean isWritable(Path path) throws IOException {
    return delegateFs.isWritable(toDelegatePath(path));
  }

  @Override
  public void setWritable(Path path, boolean writable) throws IOException {
    delegateFs.setWritable(toDelegatePath(path), writable);
  }

  @Override
  protected boolean isExecutable(Path path) throws IOException {
    return delegateFs.isExecutable(toDelegatePath(path));
  }

  @Override
  protected void setExecutable(Path path, boolean executable) throws IOException {
    delegateFs.setExecutable(toDelegatePath(path), executable);
  }

  @Override
  protected InputStream getInputStream(Path path) throws IOException {
    return delegateFs.getInputStream(toDelegatePath(path));
  }

  @Override
  protected ReadableByteChannel createReadableByteChannel(Path path) throws IOException {
    return delegateFs.createReadableByteChannel(toDelegatePath(path));
  }

  @Override
  protected OutputStream getOutputStream(Path path, boolean append) throws IOException {
    return delegateFs.getOutputStream(toDelegatePath(path), append);
  }

  @Override
  public void renameTo(Path sourcePath, Path targetPath) throws IOException {
    delegateFs.renameTo(toDelegatePath(sourcePath), toDelegatePath(targetPath));
  }

  @Override
  protected void createFSDependentHardLink(Path linkPath, Path originalPath) throws IOException {
    delegateFs.createFSDependentHardLink(toDelegatePath(linkPath), toDelegatePath(originalPath));
  }

  @Override
  public String getFileSystemType(Path path) {
    return delegateFs.getFileSystemType(toDelegatePath(path));
  }

  @Override
  public void deleteTree(Path path) throws IOException {
    delegateFs.deleteTree(toDelegatePath(path));
  }

  @Override
  public void deleteTreesBelow(Path dir) throws IOException {
    delegateFs.deleteTreesBelow(toDelegatePath(dir));
  }

  @Override
  public byte[] getxattr(Path path, String name, boolean followSymlinks) throws IOException {
    return delegateFs.getxattr(toDelegatePath(path), name, followSymlinks);
  }

  @Override
  protected byte[] getFastDigest(Path path) throws IOException {
    return delegateFs.getFastDigest(toDelegatePath(path));
  }

  @Override
  protected byte[] getDigest(Path path) throws IOException {
    return delegateFs.getDigest(toDelegatePath(path));
  }

  @Override
  protected PathFragment resolveOneLink(Path path) throws IOException {
    return delegateFs.resolveOneLink(toDelegatePath(path));
  }

  @Override
  protected Path resolveSymbolicLinks(Path path) throws IOException {
    return fromDelegatePath(delegateFs.resolveSymbolicLinks(toDelegatePath(path)));
  }

  @Override
  protected FileStatus stat(Path path, boolean followSymlinks) throws IOException {
    return delegateFs.stat(toDelegatePath(path), followSymlinks);
  }

  @Override
  protected FileStatus statNullable(Path path, boolean followSymlinks) {
    return delegateFs.statNullable(toDelegatePath(path), followSymlinks);
  }

  @Override
  protected FileStatus statIfFound(Path path, boolean followSymlinks) throws IOException {
    return delegateFs.statIfFound(toDelegatePath(path), followSymlinks);
  }

  @Override
  protected PathFragment readSymbolicLinkUnchecked(Path path) throws IOException {
    return delegateFs.readSymbolicLink(toDelegatePath(path));
  }

  @Override
  protected Collection<Dirent> readdir(Path path, boolean followSymlinks) throws IOException {
    return delegateFs.readdir(toDelegatePath(path), followSymlinks);
  }

  @Override
  protected void chmod(Path path, int mode) throws IOException {
    delegateFs.chmod(toDelegatePath(path), mode);
  }

  @Override
  protected void createHardLink(Path linkPath, Path originalPath) throws IOException {
    delegateFs.createHardLink(toDelegatePath(linkPath), toDelegatePath(originalPath));
  }

  @Override
  protected void prefetchPackageAsync(Path path, int maxDirs) {
    delegateFs.prefetchPackageAsync(toDelegatePath(path), maxDirs);
  }

  protected final Path toDelegatePath(Path path) {
    Preconditions.checkArgument(path.getFileSystem() == this);
    return Path.create(path.getPathString(), delegateFs);
  }

  protected final Path fromDelegatePath(Path delegatePath) {
    Preconditions.checkArgument(delegatePath.getFileSystem() == delegateFs);
    return Path.create(delegatePath.getPathString(), this);
  }
}
