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

import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.idea.blaze.base.ideinfo.CIdeInfo;
import com.google.idea.blaze.base.ideinfo.CToolchainIdeInfo;
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
import com.google.idea.blaze.base.sync.workspace.ExecutionRootPathResolver;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.cidr.lang.workspace.headerRoots.HeaderRoots;
import com.jetbrains.cidr.lang.workspace.headerRoots.HeadersSearchRoot;
import com.jetbrains.cidr.lang.workspace.headerRoots.IncludedHeadersRoot;
import com.jetbrains.cidr.toolchains.CompilerInfoCache;
import java.io.File;
import java.util.Objects;

/** Data used by a {@link BlazeResolveConfiguration}. */
final class BlazeResolveConfigurationData {

  final BlazeCompilerSettings compilerSettings;

  final ImmutableList<HeadersSearchRoot> cLibraryIncludeRoots;
  final ImmutableList<HeadersSearchRoot> cppLibraryIncludeRoots;
  final HeaderRoots projectIncludeRoots;
  final BlazeCompilerMacros compilerMacros;
  final CToolchainIdeInfo toolchainIdeInfo;

  static BlazeResolveConfigurationData create(
      Project project,
      ExecutionRootPathResolver executionRootPathResolver,
      ImmutableMap<File, VirtualFile> headerRoots,
      CIdeInfo cIdeInfo,
      CToolchainIdeInfo toolchainIdeInfo,
      BlazeCompilerSettings compilerSettings,
      CompilerInfoCache compilerInfoCache) {
    ImmutableSet.Builder<ExecutionRootPath> systemIncludesBuilder = ImmutableSet.builder();
    systemIncludesBuilder.addAll(cIdeInfo.transitiveSystemIncludeDirectories);
    systemIncludesBuilder.addAll(toolchainIdeInfo.builtInIncludeDirectories);
    systemIncludesBuilder.addAll(toolchainIdeInfo.unfilteredToolchainSystemIncludes);

    ImmutableSet.Builder<ExecutionRootPath> userIncludesBuilder = ImmutableSet.builder();
    userIncludesBuilder.addAll(cIdeInfo.transitiveIncludeDirectories);
    userIncludesBuilder.addAll(cIdeInfo.localIncludeDirectories);

    ImmutableSet.Builder<ExecutionRootPath> userQuoteIncludesBuilder = ImmutableSet.builder();
    userQuoteIncludesBuilder.addAll(cIdeInfo.transitiveQuoteIncludeDirectories);

    ImmutableList.Builder<String> defines = ImmutableList.builder();
    defines.addAll(cIdeInfo.transitiveDefines);
    defines.addAll(cIdeInfo.localDefines);

    ImmutableMap<String, String> features = ImmutableMap.of();

    return new BlazeResolveConfigurationData(
        project,
        executionRootPathResolver,
        headerRoots,
        systemIncludesBuilder.build(),
        systemIncludesBuilder.build(),
        userQuoteIncludesBuilder.build(),
        userIncludesBuilder.build(),
        userIncludesBuilder.build(),
        defines.build(),
        features,
        compilerSettings,
        compilerInfoCache,
        toolchainIdeInfo);
  }

  private BlazeResolveConfigurationData(
      Project project,
      ExecutionRootPathResolver executionRootPathResolver,
      ImmutableMap<File, VirtualFile> headerRoots,
      ImmutableCollection<ExecutionRootPath> cSystemIncludeDirs,
      ImmutableCollection<ExecutionRootPath> cppSystemIncludeDirs,
      ImmutableCollection<ExecutionRootPath> quoteIncludeDirs,
      ImmutableCollection<ExecutionRootPath> cIncludeDirs,
      ImmutableCollection<ExecutionRootPath> cppIncludeDirs,
      ImmutableCollection<String> defines,
      ImmutableMap<String, String> features,
      BlazeCompilerSettings compilerSettings,
      CompilerInfoCache compilerInfoCache,
      CToolchainIdeInfo toolchainIdeInfo) {
    this.toolchainIdeInfo = toolchainIdeInfo;

    HeaderRootsCollector headerRootsCollector =
        new HeaderRootsCollector(project, executionRootPathResolver, headerRoots);
    ImmutableList.Builder<HeadersSearchRoot> cIncludeRootsBuilder = ImmutableList.builder();
    headerRootsCollector.collectHeaderRoots(
        cIncludeRootsBuilder, cIncludeDirs, true /* isUserHeader */);
    headerRootsCollector.collectHeaderRoots(
        cIncludeRootsBuilder, cSystemIncludeDirs, false /* isUserHeader */);
    this.cLibraryIncludeRoots = cIncludeRootsBuilder.build();

    ImmutableList.Builder<HeadersSearchRoot> cppIncludeRootsBuilder = ImmutableList.builder();
    headerRootsCollector.collectHeaderRoots(
        cppIncludeRootsBuilder, cppIncludeDirs, true /* isUserHeader */);
    headerRootsCollector.collectHeaderRoots(
        cppIncludeRootsBuilder, cppSystemIncludeDirs, false /* isUserHeader */);
    this.cppLibraryIncludeRoots = cppIncludeRootsBuilder.build();

    ImmutableList.Builder<HeadersSearchRoot> quoteIncludeRootsBuilder = ImmutableList.builder();
    headerRootsCollector.collectHeaderRoots(
        quoteIncludeRootsBuilder, quoteIncludeDirs, true /* isUserHeader */);
    this.projectIncludeRoots = new HeaderRoots(quoteIncludeRootsBuilder.build());

    this.compilerSettings = compilerSettings;
    this.compilerMacros =
        new BlazeCompilerMacros(project, compilerInfoCache, compilerSettings, defines, features);
  }

  @Override
  public boolean equals(Object other) {
    if (this == other) {
      return true;
    }
    if (!(other instanceof BlazeResolveConfigurationData)) {
      return false;
    }
    BlazeResolveConfigurationData otherData = (BlazeResolveConfigurationData) other;
    return this.cLibraryIncludeRoots.equals(otherData.cLibraryIncludeRoots)
        && this.cppLibraryIncludeRoots.equals(otherData.cppLibraryIncludeRoots)
        && this.projectIncludeRoots.equals(otherData.projectIncludeRoots)
        && this.compilerMacros.equals(otherData.compilerMacros)
        && this.toolchainIdeInfo.equals(otherData.toolchainIdeInfo)
        && this.compilerSettings
            .getCompilerVersion()
            .equals(otherData.compilerSettings.getCompilerVersion());
  }

  @Override
  public int hashCode() {
    return Objects.hash(
        cLibraryIncludeRoots,
        cppLibraryIncludeRoots,
        projectIncludeRoots,
        compilerMacros,
        toolchainIdeInfo,
        compilerSettings.getCompilerVersion());
  }

  private static class HeaderRootsCollector {
    private final Project project;
    private final ExecutionRootPathResolver executionRootPathResolver;
    private final ImmutableMap<File, VirtualFile> virtualFileCache;

    HeaderRootsCollector(
        Project project,
        ExecutionRootPathResolver executionRootPathResolver,
        ImmutableMap<File, VirtualFile> virtualFileCache) {
      this.project = project;
      this.executionRootPathResolver = executionRootPathResolver;
      this.virtualFileCache = virtualFileCache;
    }

    void collectHeaderRoots(
        ImmutableList.Builder<HeadersSearchRoot> roots,
        ImmutableCollection<ExecutionRootPath> paths,
        boolean isUserHeader) {
      for (ExecutionRootPath executionRootPath : paths) {
        ImmutableList<File> possibleDirectories =
            executionRootPathResolver.resolveToIncludeDirectories(executionRootPath);
        for (File f : possibleDirectories) {
          VirtualFile vf = virtualFileCache.get(f);
          if (vf != null) {
            roots.add(new IncludedHeadersRoot(project, vf, false /* recursive */, isUserHeader));
          }
        }
      }
    }
  }
}
