// Copyright 2016 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.skyframe;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.UnixJniLoader;
import com.google.devtools.common.options.OptionsProvider;
import java.io.File;
import java.nio.file.Path;

/**
 * A {@link DiffAwareness} that use fsevents to watch the filesystem to use in lieu of
 * {@link LocalDiffAwareness}.
 *
 * <p>On OS X, the local diff awareness cannot work because WatchService is dummy and do polling,
 * which is slow (https://bugs.openjdk.java.net/browse/JDK-7133447).
 */
public final class MacOSXFsEventsDiffAwareness extends LocalDiffAwareness {
  private final double latency;

  private boolean closed;

  // Keep a pointer to a native structure in the JNI code (the FsEvents callback needs that
  // structure).
  private long nativePointer;

  private boolean opened;

  /**
   * Watch changes on the file system under <code>watchRoot</code> with a granularity of
   * <code>delay</code> seconds.
   */
  MacOSXFsEventsDiffAwareness(String watchRoot, double latency) {
    super(watchRoot);
    this.latency = latency;
  }

  /**
   * Watch changes on the file system under <code>watchRoot</code> with a granularity of 5ms.
   */
  MacOSXFsEventsDiffAwareness(String watchRoot) {
    this(watchRoot, 0.005);
  }

  /**
   * Helper function to start the watch of <code>paths</code>, called by the constructor.
   */
  private native void create(String[] paths, double latency);

  /**
   * Run the main loop
   */
  private native void run();

  private void init() {
    // The code below is based on the assumption that init() can never fail, which is currently the
    // case; if you change init(), then you also need to update {@link #getCurrentView}.
    Preconditions.checkState(!opened);
    opened = true;
    create(new String[] {watchRootPath.toAbsolutePath().toString()}, latency);
    // Start a thread that just contains the OS X run loop.
    new Thread(
            new Runnable() {
              @Override
              public void run() {
                MacOSXFsEventsDiffAwareness.this.run();
              }
            })
        .start();
  }

  /**
   * Close this watch service, this service should not be used any longer after closing.
   */
  @Override
  public void close() {
    if (opened) {
      Preconditions.checkState(!closed);
      closed = true;
      doClose();
    }
  }

  private static final boolean JNI_AVAILABLE;

  /**
   * JNI code stopping the main loop and shutting down listening to FSEvents.
   */
  private native void doClose();

  /**
   * JNI code returning the list of absolute path modified since last call.
   */
  private native String[] poll();

  static {
    boolean loadJniWorked = false;
    try {
      UnixJniLoader.loadJni();
      loadJniWorked = true;
    } catch (UnsatisfiedLinkError ignored) {
      // Unfortunately, we compile this class into the Bazel bootstrap binary, which doesn't have
      // access to the JNI code (to simplify bootstrap). This is the quick and dirty way to
      // hard-disable --watchfs in the bootstrap binary.
    }
    JNI_AVAILABLE = loadJniWorked;
  }

  @Override
  public View getCurrentView(OptionsProvider options)
      throws BrokenDiffAwarenessException {
    if (!JNI_AVAILABLE) {
      return EVERYTHING_MODIFIED;
    }
    // See WatchServiceDiffAwareness#getCurrentView for an explanation of this logic.
    boolean watchFs = options.getOptions(Options.class).watchFS;
    if (watchFs && !opened) {
      init();
    } else if (!watchFs && opened) {
      close();
      throw new BrokenDiffAwarenessException("Switched off --watchfs again");
    } else if (!opened) {
      // The only difference with WatchServiceDiffAwareness#getCurrentView is this if; the init()
      // call above can never fail, so we don't need to re-check the opened flag after init().
      return EVERYTHING_MODIFIED;
    }
    Preconditions.checkState(!closed);
    ImmutableSet.Builder<Path> paths = ImmutableSet.builder();
    for (String path : poll()) {
      paths.add(new File(path).toPath());
    }
    return newView(paths.build());
  }
}
