/*
 * 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.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.editor.Document;
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;

  public 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;
  }

  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 static 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 manager = FileDocumentManager.getInstance();
        Document doc = manager.getCachedDocument(file);
        if (doc != null) {
          manager.saveDocument(doc);
        }
      }
    }
  }

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

  private static boolean isBuildFile(VirtualFile file) {
    return file.getName().equals("BUILD");
  }
}
