/*
 * Copyright 2012-present Facebook, Inc.
 *
 * 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.facebook.buck.util;

import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.createStrictMock;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.eventbus.EventBus;

import org.easymock.Capture;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitor;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;

public class ProjectFilesystemWatcherTest {

  private EventBus eventBus;
  private ProjectFilesystem filesystem;
  private WatchService watchService;
  private Path path;
  private WatchKey key;
  private WatchEvent<Path> event;
  private Capture<FileVisitor<Path>> visitor;
  private ProjectFilesystemWatcher watcher;

  @Before
  @SuppressWarnings("unchecked") // Needed to mock generic class.
  public void setUp() throws IOException {
    eventBus = createStrictMock(EventBus.class);
    filesystem = createNiceMock(ProjectFilesystem.class);
    watchService = createNiceMock(WatchService.class);
    path = createNiceMock(Path.class);
    key = createNiceMock(WatchKey.class);
    event = createNiceMock(WatchEvent.class);

    expect(filesystem.getProjectRoot()).andReturn(new File("/"));
    visitor = new Capture<>();
    filesystem.walkFileTree(anyObject(Path.class), capture(visitor));
    expect(path.normalize()).andReturn(path);
    expect(path.register(anyObject(WatchService.class),
        eq(StandardWatchEventKinds.ENTRY_CREATE),
        eq(StandardWatchEventKinds.ENTRY_DELETE),
        eq(StandardWatchEventKinds.ENTRY_MODIFY))).andReturn(key);
  }

  @Test
  public void noEventsPostedWhenNoFilesChange() throws IOException {

    // Return no events when WatchService is polled.
    expect(watchService.poll()).andReturn(null);

    replay(filesystem, eventBus, watchService, path, key, event);

    // Pump ProjectFilesystemWatcher.
    watcher = new ProjectFilesystemWatcher(
        filesystem, eventBus, ImmutableSet.<String>of(), watchService);
    visitor.getValue().preVisitDirectory(path, null);
    watcher.postEvents();

    // Check no events were posted to EventBus.
    verify(filesystem, eventBus, watchService, path, key, event);
  }

  @Test
  public void eventPostedWhenFileChanged() throws IOException {

    // Return a single create event when WatchService polled.
    expect(watchService.poll()).andReturn(key).andReturn(null);
    expect(key.pollEvents()).andReturn(Lists.<WatchEvent<?>>newArrayList(event));
    expect(filesystem.isPathChangeEvent(anyObject(WatchEvent.class))).andReturn(true).anyTimes();
    expect(event.context()).andReturn(path);
    expect(path.resolve(anyObject(Path.class))).andReturn(path);
    expect(path.normalize()).andReturn(path);
    expect(filesystem.isDirectory(
        anyObject(Path.class), eq(LinkOption.NOFOLLOW_LINKS))).andReturn(false);
    expect(key.reset()).andReturn(false);
    eventBus.post(anyObject(WatchEvent.class));
    replay(filesystem, eventBus, watchService, path, key, event);

    // Pump ProjectFilesystemWatcher.
    watcher = new ProjectFilesystemWatcher(
        filesystem, eventBus, ImmutableSet.<String>of(), watchService);
    visitor.getValue().preVisitDirectory(path, null);
    watcher.postEvents();

    // Check event was posted to EventBus.
    verify(filesystem, eventBus, watchService, path, key, event);
  }

  @Test
  public void noEventPostedWhenFileExcluded() throws IOException {

    // Return a single modify event when WatchService polled.
    expect(watchService.poll()).andReturn(key).andReturn(null);
    expect(key.pollEvents()).andReturn(Lists.<WatchEvent<?>>newArrayList(event));
    expect(filesystem.isPathChangeEvent(anyObject(WatchEvent.class))).andReturn(true).anyTimes();
    expect(event.context()).andReturn(path);
    expect(path.resolve(anyObject(Path.class))).andReturn(path);
    expect(path.normalize()).andReturn(path);
    expect(path.startsWith(anyObject(String.class))).andReturn(false).andReturn(true);
    expect(key.reset()).andReturn(false);
    replay(filesystem, eventBus, watchService, path, key, event);

    // Pump ProjectFilesystemWatcher.
    watcher = new ProjectFilesystemWatcher(
        filesystem, eventBus, ImmutableSet.<String>of("/"), watchService);
    visitor.getValue().preVisitDirectory(path, null);
    watcher.postEvents();

    // Check event was posted to EventBus.
    verify(filesystem, eventBus, watchService, path, key, event);
  }
}
