/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#ifndef cmSourceFileLocation_h
#define cmSourceFileLocation_h

#include "cmConfigure.h" // IWYU pragma: keep

#include <string>

#include "cmSourceFileLocationKind.h"

class cmMakefile;

/** \class cmSourceFileLocation
 * \brief cmSourceFileLocation tracks knowledge about a source file location
 *
 * Source files can be referenced by a variety of names.  The
 * directory and/or extension may be omitted leading to a certain
 * level of ambiguity about the source file location.  This class is
 * used by cmSourceFile to keep track of what is known about the
 * source file location.  Each reference may add some information
 * about the directory or extension of the file.
 */
class cmSourceFileLocation
{
public:
  /**
   * Construct for a source file created in a given cmMakefile
   * instance with an initial name.
   */
  cmSourceFileLocation(
    cmMakefile const* mf, const std::string& name,
    cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous);
  cmSourceFileLocation();
  cmSourceFileLocation(const cmSourceFileLocation& loc);

  /**
   * Return whether the given source file location could refers to the
   * same source file as this location given the level of ambiguity in
   * each location.
   */
  bool Matches(cmSourceFileLocation const& loc);

  /**
   * Explicitly state that the source file is located in the source tree.
   */
  void DirectoryUseSource();

  /**
   * Explicitly state that the source file is located in the build tree.
   */
  void DirectoryUseBinary();

  /**
   * Return whether the directory containing the source is ambiguous.
   */
  bool DirectoryIsAmbiguous() const { return this->AmbiguousDirectory; }

  /**
   * Return whether the extension of the source name is ambiguous.
   */
  bool ExtensionIsAmbiguous() const { return this->AmbiguousExtension; }

  /**
   * Get the directory containing the file as best is currently known.
   * If DirectoryIsAmbiguous() returns false this will be a full path.
   * Otherwise it will be a relative path (possibly empty) that is
   * either with respect to the source or build tree.
   */
  const std::string& GetDirectory() const { return this->Directory; }

  /**
   * Get the file name as best is currently known.  If
   * ExtensionIsAmbiguous() returns true this name may not be the
   * final name (but could be).  Otherwise the returned name is the
   * final name.
   */
  const std::string& GetName() const { return this->Name; }

  /**
   * Get the cmMakefile instance for which the source file was created.
   */
  cmMakefile const* GetMakefile() const { return this->Makefile; }

private:
  cmMakefile const* const Makefile;
  bool AmbiguousDirectory;
  bool AmbiguousExtension;
  std::string Directory;
  std::string Name;

  bool MatchesAmbiguousExtension(cmSourceFileLocation const& loc) const;

  // Update the location with additional knowledge.
  void Update(cmSourceFileLocation const& loc);
  void UpdateExtension(const std::string& name);

  cmSourceFileLocation& operator=(const cmSourceFileLocation& loc) = delete;
};

#endif
