/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * 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 org.jetbrains.plugins.gradle.service;

import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.externalSystem.ExternalSystemManager;
import com.intellij.openapi.externalSystem.model.project.ExternalModuleBuildClasspathPojo;
import com.intellij.openapi.externalSystem.model.project.ExternalProjectBuildClasspathPojo;
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.util.GradleConstants;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author Vladislav.Soroka
 * @since 12/27/13
 */
public class GradleBuildClasspathManager {
  @NotNull
  private final Project myProject;

  @NotNull
  private volatile List<VirtualFile> allFilesCache;

  @NotNull
  private final AtomicReference<Map<String/*module path*/, List<VirtualFile> /*module build classpath*/>> myClasspathMap
    = new AtomicReference<Map<String, List<VirtualFile>>>(new HashMap<String, List<VirtualFile>>());

  public GradleBuildClasspathManager(@NotNull Project project) {
    myProject = project;
    allFilesCache = ContainerUtil.newArrayList();
  }

  @NotNull
  public static GradleBuildClasspathManager getInstance(@NotNull Project project) {
    return ServiceManager.getService(project, GradleBuildClasspathManager.class);
  }

  public void reload() {
    ExternalSystemManager<?, ?, ?, ?, ?> manager = ExternalSystemApiUtil.getManager(GradleConstants.SYSTEM_ID);
    assert manager != null;
    AbstractExternalSystemLocalSettings localSettings = manager.getLocalSettingsProvider().fun(myProject);

    Map<String/*module path*/, List<VirtualFile> /*module build classpath*/> map = ContainerUtil.newHashMap();

    final LocalFileSystem localFileSystem = LocalFileSystem.getInstance();
    final JarFileSystem jarFileSystem = JarFileSystem.getInstance();
    for (final ExternalProjectBuildClasspathPojo projectBuildClasspathPojo : localSettings.getProjectBuildClasspath().values()) {
      final List<VirtualFile> projectBuildClasspath = ContainerUtil.newArrayList();
      ExternalSystemApiUtil.executeOnEdt(true, new Runnable() {
        @Override
        public void run() {
          for (String path : projectBuildClasspathPojo.getProjectBuildClasspath()) {
            final VirtualFile virtualFile = localFileSystem.refreshAndFindFileByPath(path);
            if (virtualFile != null) {
              ContainerUtil.addIfNotNull(
                projectBuildClasspath, virtualFile.isDirectory() ? virtualFile : jarFileSystem.getJarRootForLocalFile(virtualFile));
            }
          }
        }
      });

      for (final ExternalModuleBuildClasspathPojo moduleBuildClasspathPojo : projectBuildClasspathPojo.getModulesBuildClasspath().values()) {
        final List<VirtualFile> moduleBuildClasspath = ContainerUtil.newArrayList(projectBuildClasspath);
        ExternalSystemApiUtil.executeOnEdt(true, new Runnable() {
          @Override
          public void run() {
            for (String path : moduleBuildClasspathPojo.getEntries()) {
              final VirtualFile virtualFile = localFileSystem.refreshAndFindFileByPath(path);
              if (virtualFile != null) {
                ContainerUtil.addIfNotNull(moduleBuildClasspath, jarFileSystem.getJarRootForLocalFile(virtualFile));
              }
            }
          }
        });

        map.put(moduleBuildClasspathPojo.getPath(), moduleBuildClasspath);
      }
    }

    myClasspathMap.set(map);

    Set<VirtualFile> set = new LinkedHashSet<VirtualFile>();
    for (List<VirtualFile> virtualFiles : myClasspathMap.get().values()) {
      set.addAll(virtualFiles);
    }
    allFilesCache = ContainerUtil.newArrayList(set);
  }

  @NotNull
  public List<VirtualFile> getAllClasspathEntries() {
    checkRootsValidity(allFilesCache);
    return allFilesCache;
  }

  @NotNull
  public List<VirtualFile> getModuleClasspathEntries(@NotNull String externalModulePath) {
    checkRootsValidity(myClasspathMap.get().get(externalModulePath));
    List<VirtualFile> virtualFiles = myClasspathMap.get().get(externalModulePath);
    return virtualFiles == null ? Collections.<VirtualFile>emptyList() : virtualFiles;
  }

  private void checkRootsValidity(@Nullable List<VirtualFile> virtualFiles) {
    if (virtualFiles == null) return;

    if (!virtualFiles.isEmpty()) {
      for (VirtualFile file : virtualFiles) {
        if (!file.isValid()) {
          reload();
          break;
        }
      }
    }
  }
}
