// 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.bazel.e4b.classpath;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.osgi.service.prefs.BackingStoreException;

import com.google.devtools.bazel.e4b.Activator;
import com.google.devtools.bazel.e4b.BazelProjectSupport;
import com.google.devtools.bazel.e4b.command.BazelCommand.BazelInstance;
import com.google.devtools.bazel.e4b.command.BazelNotFoundException;
import com.google.devtools.bazel.e4b.command.IdeBuildInfo;
import com.google.devtools.bazel.e4b.command.IdeBuildInfo.Jars;

public class BazelClasspathContainer implements IClasspathContainer {
  public static final String CONTAINER_NAME = "com.google.devtools.bazel.e4b.BAZEL_CONTAINER";

  private final IPath path;
  private final IJavaProject project;
  private final BazelInstance instance;

  public BazelClasspathContainer(IPath path, IJavaProject project)
      throws IOException, InterruptedException, BackingStoreException, JavaModelException,
      BazelNotFoundException {
    this.path = path;
    this.project = project;
    this.instance = BazelProjectSupport.getBazelCommandInstance(project.getProject());
  }

  private boolean isSourcePath(String path) throws JavaModelException, BackingStoreException {
    Path pp = new File(instance.getWorkspaceRoot().toString() + File.separator + path).toPath();
    IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
    for (IClasspathEntry entry : project.getRawClasspath()) {
      if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
        IResource res = root.findMember(entry.getPath());
        if (res != null) {
          String file = res.getLocation().toOSString();
          if (!file.isEmpty() && pp.startsWith(file)) {
            IPath[] inclusionPatterns = entry.getInclusionPatterns();
            if (!matchPatterns(pp, entry.getExclusionPatterns()) && (inclusionPatterns == null
                || inclusionPatterns.length == 0 || matchPatterns(pp, inclusionPatterns))) {
              return true;
            }
          }
        }
      }
    }
    return false;
  }

  private boolean matchPatterns(Path path, IPath[] patterns) {
    if (patterns != null) {
      for (IPath p : patterns) {
        PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + p.toOSString());
        if (matcher.matches(path)) {
          return true;
        }
      }
    }
    return false;
  }

  private boolean isSourceInPaths(List<String> sources)
      throws JavaModelException, BackingStoreException {
    for (String s : sources) {
      if (isSourcePath(s)) {
        return true;
      }
    }
    return false;
  }

  @Override
  public IClasspathEntry[] getClasspathEntries() {
    try {
      List<String> targets = BazelProjectSupport.getTargets(project.getProject());
      Map<String, IdeBuildInfo> infos = instance.getIdeInfo(targets);
      Set<Jars> jars = new HashSet<>();
      for (IdeBuildInfo s : infos.values()) {
        jars.addAll(s.getGeneratedJars());
        if (!isSourceInPaths(s.getSources())) {
          jars.addAll(s.getJars());
        }
      }
      return jarsToClasspathEntries(jars);
    } catch (JavaModelException | BackingStoreException | IOException | InterruptedException e) {
      Activator.error("Unable to compute classpath containers entries.", e);
      return new IClasspathEntry[] {};
    } catch (BazelNotFoundException e) {
      Activator.error("Bazel not found: " + e.getMessage());
      return new IClasspathEntry[] {};
    }
  }

  private IClasspathEntry[] jarsToClasspathEntries(Set<Jars> jars) {
    IClasspathEntry[] entries = new IClasspathEntry[jars.size()];
    int i = 0;
    File execRoot = instance.getExecRoot();
    for (Jars j : jars) {
      entries[i] = JavaCore.newLibraryEntry(getJarIPath(execRoot, j.getJar()),
          getJarIPath(execRoot, j.getSrcJar()), null);
      i++;
    }
    return entries;
  }

  private static IPath getJarIPath(File execRoot, String file) {
    if (file == null) {
      return null;
    }
    File path = new File(execRoot, file);
    return org.eclipse.core.runtime.Path.fromOSString(path.toString());
  }

  @Override
  public String getDescription() {
    return "Bazel Classpath Container";
  }

  @Override
  public int getKind() {
    return K_APPLICATION;
  }

  @Override
  public IPath getPath() {
    return path;
  }


  public boolean isValid() {
    return instance != null;
  }
}
