/*
 * 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.idea.blaze.base.sync.status;

import com.google.idea.blaze.base.projectview.ProjectViewStorageManager;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.settings.BlazeUserSettings;
import com.google.idea.blaze.base.sync.BlazeSyncManager;
import com.google.idea.blaze.base.sync.BlazeSyncParams;
import com.google.idea.blaze.base.sync.BlazeSyncParams.SyncMode;
import com.google.idea.blaze.base.sync.SyncListener.SyncResult;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.FileEditorManagerAdapter;
import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
import com.intellij.openapi.fileEditor.FileEditorManagerListener;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileAdapter;
import com.intellij.openapi.vfs.VirtualFileEvent;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.VirtualFileMoveEvent;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicBoolean;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * Per-project listener for changes to BUILD files, and other changes requiring an incremental sync.
 */
public class BlazeSyncStatusImpl implements BlazeSyncStatus {

  public static BlazeSyncStatusImpl getImpl(@NotNull Project project) {
    return (BlazeSyncStatusImpl) BlazeSyncStatus.getInstance(project);
  }

  private static Logger log = Logger.getInstance(BlazeSyncStatusImpl.class);

  private final Project project;

  private final AtomicBoolean syncInProgress = new AtomicBoolean(false);
  private final AtomicBoolean syncPending = new AtomicBoolean(false);

  /** has a BUILD file changed since the last sync started */
  private volatile boolean dirty = false;

  private volatile boolean failedSync = false;

  public BlazeSyncStatusImpl(Project project) {
    this.project = project;
    // listen for changes to the VFS
    VirtualFileManager.getInstance().addVirtualFileListener(new FileListener(), project);

    // trigger VFS updates whenever navigating away from an unsaved BUILD file
    project
        .getMessageBus()
        .connect()
        .subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileFocusListener());
  }

  private static boolean automaticSyncEnabled() {
    return BlazeUserSettings.getInstance().getResyncAutomatically();
  }

  @Override
  public SyncStatus getStatus() {
    if (failedSync) {
      return SyncStatus.FAILED;
    }
    return dirty ? SyncStatus.DIRTY : SyncStatus.CLEAN;
  }

  @Override
  public boolean syncInProgress() {
    return syncInProgress.get();
  }

  public void syncStarted() {
    syncPending.set(false);
    syncInProgress.set(true);
  }

  public void syncEnded(SyncResult syncResult) {
    syncInProgress.set(false);
    failedSync = syncResult == SyncResult.FAILURE;
    if (syncResult == SyncResult.SUCCESS && !syncPending.get()) {
      dirty = false;
    } else if (syncResult == SyncResult.PARTIAL_SUCCESS || syncResult == SyncResult.CANCELLED) {
      dirty = true;
    }
  }

  @Override
  public void setDirty() {
    dirty = true;
    queueIncrementalSync();
  }

  @Override
  public void queueAutomaticSyncIfDirty() {
    if (dirty) {
      queueIncrementalSync();
    }
  }

  private void queueIncrementalSync() {
    if (automaticSyncEnabled() && syncPending.compareAndSet(false, true)) {
      log.info("Automatic sync started");
      BlazeSyncManager.getInstance(project)
          .requestProjectSync(
              new BlazeSyncParams.Builder("Sync", SyncMode.INCREMENTAL)
                  .setBackgroundSync(true)
                  .addProjectViewTargets(true)
                  .addWorkingSet(BlazeUserSettings.getInstance().getExpandSyncToWorkingSet())
                  .build());
    }
  }

  /**
   * Listens for changes to files which impact the sync process (BUILD files and project view files)
   */
  private class FileListener extends VirtualFileAdapter {
    @Override
    public void fileCreated(@NotNull VirtualFileEvent event) {
      processEvent(event);
    }

    @Override
    public void fileDeleted(@NotNull VirtualFileEvent event) {
      processEvent(event);
      // we (sometimes) only get one event when a directory is deleted, so check the children too.
      checkChildren(event.getFile());
    }

    @Override
    public void fileMoved(@NotNull VirtualFileMoveEvent event) {
      processEvent(event);
    }

    @Override
    public void contentsChanged(@NotNull VirtualFileEvent event) {
      processEvent(event);
    }

    private void processEvent(@NotNull VirtualFileEvent event) {
      if (isSyncSensitiveFile(event.getFile())) {
        setDirty();
      }
    }

    private void checkChildren(VirtualFile file) {
      if (!(file instanceof NewVirtualFile)) {
        return;
      }
      Collection<VirtualFile> children = ((NewVirtualFile) file).getCachedChildren();
      for (VirtualFile child : children) {
        if (isSyncSensitiveFile(child)) {
          setDirty();
          return;
        }
      }
    }
  }

  /**
   * Listens for changes to files which impact the sync process (BUILD files and project view files)
   */
  private class FileFocusListener extends FileEditorManagerAdapter {
    @Override
    public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
      processEvent(file);
    }

    @Override
    public void selectionChanged(@NotNull FileEditorManagerEvent event) {
      processEvent(event.getOldFile());
    }

    private void processEvent(@Nullable VirtualFile file) {
      if (isSyncSensitiveFile(file)) {
        FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
        if (fileDocumentManager.isFileModified(file)) {
          setDirty();
        }
      }
    }
  }

  private boolean isSyncSensitiveFile(@Nullable VirtualFile file) {
    return file != null
        && (isBuildFile(file) || ProjectViewStorageManager.isProjectViewFile(file.getPath()));
  }

  private boolean isBuildFile(VirtualFile file) {
    return Blaze.getBuildSystemProvider(project).isBuildFile(file.getName());
  }
}
