// Copyright 2014 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.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
import com.google.devtools.build.lib.profiler.Profiler;
import com.google.devtools.build.lib.profiler.ProfilerTask;
import com.google.devtools.build.lib.unix.FileAccessException;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * This class implements the FileSystem interface using direct calls to the
 * UNIX filesystem.
 */
@ThreadSafe
abstract class AbstractFileSystem extends FileSystem {

  protected static final String ERR_PERMISSION_DENIED = " (Permission denied)";
  protected static final Profiler profiler = Profiler.instance();

  @Override
  protected InputStream getInputStream(Path path) throws IOException {
    // This loop is a workaround for an apparent bug in FileInputStream.open, which delegates
    // ultimately to JVM_Open in the Hotspot JVM.  This call is not EINTR-safe, so we must do the
    // retry here.
    for (;;) {
      try {
        return createFileInputStream(path);
      } catch (FileNotFoundException e) {
        if (e.getMessage().endsWith("(Interrupted system call)")) {
          continue;
        } else {
          throw e;
        }
      }
    }
  }

  /**
   * Returns either normal or profiled FileInputStream.
   */
  private InputStream createFileInputStream(Path path) throws FileNotFoundException {
    final String name = path.toString();
    if (profiler.isActive() && (profiler.isProfiling(ProfilerTask.VFS_READ) ||
        profiler.isProfiling(ProfilerTask.VFS_OPEN))) {
      long startTime = Profiler.nanoTimeMaybe();
      try {
        // Replace default FileInputStream instance with the custom one that does profiling.
        return new FileInputStream(name) {
          @Override public int read() throws IOException {
            long startTime = Profiler.nanoTimeMaybe();
            try {
              // Note that FileInputStream#read() does *not* call any of our overriden methods,
              // so there's no concern with double counting here.
              return super.read();
            } finally {
              profiler.logSimpleTask(startTime, ProfilerTask.VFS_READ, name);
            }
          }

          @Override public int read(byte b[]) throws IOException {
            return read(b, 0, b.length);
          }
          @Override public int read(byte b[], int off, int len) throws IOException {
            long startTime = Profiler.nanoTimeMaybe();
            try {
              return super.read(b, off, len);
            } finally {
              profiler.logSimpleTask(startTime, ProfilerTask.VFS_READ, name);
            }
          }
        };
      } finally {
        profiler.logSimpleTask(startTime, ProfilerTask.VFS_OPEN, name);
      }
    } else {
      // Use normal FileInputStream instance if profiler is not enabled.
      return new FileInputStream(path.toString());
    }
  }

  /**
   * Returns either normal or profiled FileOutputStream. Should be used by subclasses
   * to create default OutputStream instance.
   */
  protected OutputStream createFileOutputStream(Path path, boolean append)
      throws FileNotFoundException {
    final String name = path.toString();
    if (profiler.isActive() && (profiler.isProfiling(ProfilerTask.VFS_WRITE) ||
        profiler.isProfiling(ProfilerTask.VFS_OPEN))) {
      long startTime = Profiler.nanoTimeMaybe();
      try {
        return new FileOutputStream(name, append) {
          @Override public void write(byte b[]) throws IOException {
            write(b, 0, b.length);
          }
          @Override public void write(byte b[], int off, int len) throws IOException {
            long startTime = Profiler.nanoTimeMaybe();
            try {
              super.write(b, off, len);
            } finally {
              profiler.logSimpleTask(startTime, ProfilerTask.VFS_WRITE, name);
            }
          }
        };
      } finally {
        profiler.logSimpleTask(startTime, ProfilerTask.VFS_OPEN, name);
      }
    } else {
      return new FileOutputStream(name, append);
    }
  }

  @Override
  protected OutputStream getOutputStream(Path path, boolean append) throws IOException {
    synchronized (path) {
      try {
        return createFileOutputStream(path, append);
      } catch (FileNotFoundException e) {
        // Why does it throw a *FileNotFoundException* if it can't write?
        // That does not make any sense! And its in a completely different
        // format than in other situations, no less!
        if (e.getMessage().equals(path + ERR_PERMISSION_DENIED)) {
          throw new FileAccessException(e.getMessage());
        }
        throw e;
      }
    }
  }
}
