// Copyright 2014 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.build.lib.rules.cpp;

import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.util.FileType;
import com.google.devtools.build.lib.util.FileTypeSet;
import com.google.devtools.build.lib.vfs.OsPathPolicy;
import java.util.regex.Pattern;

/**
 * C++-related file type definitions.
 */
public final class CppFileTypes {
  private static final OsPathPolicy OS = OsPathPolicy.getFilePathOs();

  // .cu and .cl are CUDA and OpenCL source extensions, respectively. They are expected to only be
  // supported with clang. Bazel is not officially supporting these targets, and the extensions are
  // listed only as long as they work with the existing C++ actions.
  // FileType is extended to use case-sensitive comparison also on Windows
  public static final FileType CPP_SOURCE =
      new FileType() {
        final ImmutableList<String> extensions =
            ImmutableList.of(".cc", ".cpp", ".cxx", ".c++", ".C", ".cu", ".cl");

        @Override
        public boolean apply(String path) {
          for (String ext : extensions) {
            if (path.endsWith(ext)) {
              return true;
            }
          }
          return false;
        }

        @Override
        public ImmutableList<String> getExtensions() {
          return extensions;
        }
      };

  // FileType is extended to use case-sensitive comparison also on Windows
  public static final FileType C_SOURCE =
      new FileType() {
        final String ext = ".c";

        @Override
        public boolean apply(String path) {
          return path.endsWith(ext);
        }

        @Override
        public ImmutableList<String> getExtensions() {
          return ImmutableList.of(ext);
        }
      };

  public static final FileType OBJC_SOURCE = FileType.of(".m");
  public static final FileType OBJCPP_SOURCE = FileType.of(".mm");
  public static final FileType CLIF_INPUT_PROTO = FileType.of(".ipb");
  public static final FileType CLIF_OUTPUT_PROTO = FileType.of(".opb");
  public static final FileType BC_SOURCE = FileType.of(".bc");

  public static final FileTypeSet ALL_C_CLASS_SOURCE =
      FileTypeSet.of(
          CppFileTypes.CPP_SOURCE,
          CppFileTypes.C_SOURCE,
          CppFileTypes.OBJCPP_SOURCE,
          CppFileTypes.OBJC_SOURCE,
          CppFileTypes.CLIF_INPUT_PROTO);

  // Filetypes that generate LLVM bitcode when -flto is specified.
  public static final FileTypeSet LTO_SOURCE =
      FileTypeSet.of(CppFileTypes.CPP_SOURCE, CppFileTypes.C_SOURCE);

  public static final FileType CPP_HEADER =
      FileType.of(
          ".h", ".hh", ".hpp", ".ipp", ".hxx", ".h++", ".inc", ".inl", ".tlh", ".tli", ".H",
          ".tcc");
  public static final FileType PCH = FileType.of(".pch");
  public static final FileTypeSet OBJC_HEADER = FileTypeSet.of(CPP_HEADER, PCH);

  public static final FileType CPP_TEXTUAL_INCLUDE = FileType.of(".inc");

  public static final FileType PIC_PREPROCESSED_C = FileType.of(".pic.i");
  public static final FileType PREPROCESSED_C =
      new FileType() {
        final String ext = ".i";

        @Override
        public boolean apply(String path) {
          return OS.endsWith(path, ext) && !PIC_PREPROCESSED_C.matches(path);
        }

        @Override
        public ImmutableList<String> getExtensions() {
          return ImmutableList.of(ext);
        }
      };
  public static final FileType PIC_PREPROCESSED_CPP = FileType.of(".pic.ii");
  public static final FileType PREPROCESSED_CPP =
      new FileType() {
        final String ext = ".ii";

        @Override
        public boolean apply(String path) {
          return OS.endsWith(path, ext) && !PIC_PREPROCESSED_CPP.matches(path);
        }

        @Override
        public ImmutableList<String> getExtensions() {
          return ImmutableList.of(ext);
        }
      };

  // FileType is extended to use case-sensitive comparison also on Windows
  public static final FileType ASSEMBLER_WITH_C_PREPROCESSOR =
      new FileType() {
        final String ext = ".S";

        @Override
        public boolean apply(String path) {
          return path.endsWith(ext);
        }

        @Override
        public ImmutableList<String> getExtensions() {
          return ImmutableList.of(ext);
        }
      };

  // FileType is extended to use case-sensitive comparison also on Windows
  public static final FileType PIC_ASSEMBLER =
      new FileType() {
        final String ext = ".pic.s";

        @Override
        public boolean apply(String path) {
          return OS.endsWith(path, ext) && path.endsWith(".s");
        }

        @Override
        public ImmutableList<String> getExtensions() {
          return ImmutableList.of(ext);
        }
      };

  // FileType is extended to use case-sensitive comparison also on Windows
  public static final FileType ASSEMBLER =
      new FileType() {
        final String ext = ".s";

        @Override
        public boolean apply(String path) {
          return (path.endsWith(ext) && !PIC_ASSEMBLER.matches(path)) || OS.endsWith(path, ".asm");
        }

        @Override
        public ImmutableList<String> getExtensions() {
          return ImmutableList.of(ext, ".asm");
        }
      };

  public static final FileType PIC_ARCHIVE = FileType.of(".pic.a");
  public static final FileType ARCHIVE =
      new FileType() {
        final ImmutableList<String> extensions = ImmutableList.of(".a", ".lib");

        @Override
        public boolean apply(String path) {
          if (PIC_ARCHIVE.matches(path)
              || ALWAYS_LINK_LIBRARY.matches(path)
              || OS.endsWith(path, ".if.lib")) {
            return false;
          }
          for (String ext : extensions) {
            if (OS.endsWith(path, ext)) {
              return true;
            }
          }
          return false;
        }

        @Override
        public ImmutableList<String> getExtensions() {
          return extensions;
        }
      };

  public static final FileType ALWAYS_LINK_PIC_LIBRARY = FileType.of(".pic.lo");
  public static final FileType ALWAYS_LINK_LIBRARY =
      new FileType() {
        final String ext = ".lo";

        @Override
        public boolean apply(String path) {
          return (OS.endsWith(path, ext) && !ALWAYS_LINK_PIC_LIBRARY.matches(path))
              || OS.endsWith(path, ".lo.lib");
        }

        @Override
        public ImmutableList<String> getExtensions() {
          return ImmutableList.of(ext, ".lo.lib");
        }
      };

  public static final FileType PIC_OBJECT_FILE = FileType.of(".pic.o");
  public static final FileType OBJECT_FILE =
      new FileType() {
        final String ext = ".o";

        @Override
        public boolean apply(String path) {
          return (OS.endsWith(path, ext) && !PIC_OBJECT_FILE.matches(path))
              || OS.endsWith(path, ".obj");
        }

        @Override
        public ImmutableList<String> getExtensions() {
          return ImmutableList.of(ext, ".obj");
        }
      };
  // Static library artifact created by rustc, can be used as a regular archive.
  public static final FileType RUST_RLIB = FileType.of(".rlib");

  // Minimized bitcode file emitted by the ThinLTO compile step and used just for LTO indexing.
  public static final FileType LTO_INDEXING_OBJECT_FILE = FileType.of(".indexing.o");

  // Imports file emitted by the ThinLTO indexing step and used for LTO backend action.
  public static final FileType LTO_IMPORTS_FILE = FileType.of(".imports");

  // Indexing analysis result file emitted by the ThinLTO indexing step and used for LTO backend
  // action.
  public static final FileType LTO_INDEXING_ANALYSIS_FILE = FileType.of(".thinlto.bc");

  // TODO(bazel-team): File types should not be read from this hard-coded list but should come from
  // the toolchain instead. See https://github.com/bazelbuild/bazel/issues/17117
  public static final FileType SHARED_LIBRARY =
      FileType.of(".so", ".dylib", ".dll", ".pyd", ".wasm", ".tgt", ".vpi");
  // Unix shared libraries can be passed to linker, but not .dll on Windows
  public static final FileType UNIX_SHARED_LIBRARY = FileType.of(".so", ".dylib");
  public static final FileType INTERFACE_SHARED_LIBRARY =
      FileType.of(".ifso", ".tbd", ".lib", ".dll.a");
  public static final FileType LINKER_SCRIPT = FileType.of(".ld", ".lds", ".ldscript");

  // Windows DEF file: https://msdn.microsoft.com/en-us/library/28d6s79h.aspx
  public static final FileType WINDOWS_DEF_FILE = FileType.of(".def");

  // Matches shared libraries with version names in the extension, i.e.
  // libmylib.so.2 or libmylib.so.2.10 or libmylib.so.1a_b35.
  private static final Pattern VERSIONED_SHARED_LIBRARY_PATTERN =
      Pattern.compile("^.+\\.((so)|(dylib))(\\.\\d\\w*)+$");
  public static final FileType VERSIONED_SHARED_LIBRARY =
      new FileType() {
        @Override
        public boolean apply(String path) {
          // Because regex matching can be slow, we first do a quick check for ".so." and ".dylib."
          // substring before risking the full-on regex match. This should eliminate the performance
          // hit on practically every non-qualifying file type.
          if (!path.contains(".so.") && !path.contains(".dylib.")) {
            return false;
          }
          return VERSIONED_SHARED_LIBRARY_PATTERN.matcher(path).matches();
        }
      };

  public static final FileType COVERAGE_NOTES = FileType.of(".gcno");
  public static final FileType GCC_AUTO_PROFILE = FileType.of(".afdo");
  public static final FileType XBINARY_PROFILE = FileType.of(".xfdo");
  public static final FileType LLVM_PROFILE = FileType.of(".profdata");
  public static final FileType LLVM_PROFILE_RAW = FileType.of(".profraw");
  public static final FileType LLVM_PROFILE_ZIP = FileType.of(".zip");

  public static final FileType CPP_MODULE_MAP = FileType.of(".cppmap");
  public static final FileType CPP_MODULE = FileType.of(".pcm");
  public static final FileType OBJC_MODULE_MAP = FileType.of("module.modulemap");

  /** Predicate that matches all artifacts that can be used in an objc Clang module map. */
  public static final Predicate<Artifact> MODULE_MAP_HEADER =
      artifact -> {
        if (artifact.isTreeArtifact()) {
          // Tree artifact is basically a directory, which does not have any information about
          // the contained files and their extensions. Here we assume the passed in tree artifact
          // contains proper header files with .h extension.
          return true;
        } else {
          // The current clang (clang-600.0.57) on Darwin doesn't support 'textual', so we can't
          // have '.inc' files in the module map (since they're implictly textual).
          // TODO(bazel-team): Use HEADERS file type once clang-700 is the base clang we support.
          return OS.endsWith(artifact.getFilename(), ".h");
        }
      };

  public static final boolean headerDiscoveryRequired(Artifact source) {
    String fileName = source.getFilename();
    return !ASSEMBLER.matches(fileName)
        && !PIC_ASSEMBLER.matches(fileName)
        && !CPP_MODULE.matches(fileName);
  }

  private CppFileTypes() {}
}
