// 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.
  public static final FileType CPP_SOURCE =
      FileType.of(".cc", ".cpp", ".cxx", ".c++", ".C", ".cu", ".cl");
  public static final FileType C_SOURCE = FileType.of(".c");
  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");

  // 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");
  // 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() {}
}
