/* C++ modules.  Experimental!	-*- c++ -*-
   Copyright (C) 2017-2022 Free Software Foundation, Inc.
   Written by Nathan Sidwell <nathan@acm.org> while at FaceBook

   This file is part of GCC.

   GCC is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   GCC is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"

#include "resolver.h"
// C++
#include <algorithm>
#include <memory>
// C
#include <cstring>
// OS
#include <fcntl.h>
#include <unistd.h>
#if 0 // 1 for testing no mmap
#define MAPPED_READING 0
#else
#ifdef IN_GCC
#if HAVE_MMAP_FILE && _POSIX_MAPPED_FILES > 0
#define MAPPED_READING 1
#else
#define MAPPED_READING 0
#endif
#else
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#define MAPPED_READING 1
#else
#define MAPPED_READING 0
#endif
#endif
#endif

#include <sys/types.h>
#include <sys/stat.h>

#if !defined (IN_GCC) && !MAPPED_READING
#define xmalloc(X) malloc(X)
#endif

#if !HOST_HAS_O_CLOEXEC
#define O_CLOEXEC 0
#endif

#ifndef DIR_SEPARATOR
#define DIR_SEPARATOR '/'
#endif

module_resolver::module_resolver (bool map, bool xlate)
  : default_map (map), default_translate (xlate)
{
}

module_resolver::~module_resolver ()
{
  if (fd_repo >= 0)
    close (fd_repo);
}

bool
module_resolver::set_repo (std::string &&r, bool force)
{
  if (force || repo.empty ())
    {
      repo = std::move (r);
      force = true;
    }
  return force;
}

bool
module_resolver::add_mapping (std::string &&module, std::string &&file,
			      bool force)
{
  auto res = map.emplace (std::move (module), std::move (file));
  if (res.second)
    force = true;
  else if (force)
    res.first->second = std::move (file);

  return force;
}

int
module_resolver::read_tuple_file (int fd, char const *prefix, bool force)
{
  struct stat stat;
  if (fstat (fd, &stat) < 0)
    return -errno;

  if (!stat.st_size)
    return 0;

  void *buffer = nullptr;
#if MAPPED_READING
  // Just map the file, we're gonna read all of it, so no need for
  // line buffering
  buffer = mmap (nullptr, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
  if (buffer == MAP_FAILED)
    return -errno;
  struct Deleter {
    void operator()(void* p) const { munmap(p, size); }
    size_t size;
  };
  std::unique_ptr<void, Deleter> guard(buffer, Deleter{(size_t)stat.st_size});
#else
  buffer = xmalloc (stat.st_size);
  if (!buffer)
    return -errno;
  struct Deleter { void operator()(void* p) const { free(p); } };
  std::unique_ptr<void, Deleter> guard(buffer);
  if (read (fd, buffer, stat.st_size) != stat.st_size)
    return -errno;
#endif

  size_t prefix_len = prefix ? strlen (prefix) : 0;
  unsigned lineno = 0;

  for (char const *begin = reinterpret_cast <char const *> (buffer),
	 *end = begin + stat.st_size, *eol;
       begin != end; begin = eol + 1)
    {
      lineno++;
      eol = std::find (begin, end, '\n');
      if (eol == end)
	// last line has no \n, ignore the line, you lose
	break;

      auto *pos = begin;
      bool pfx_search = prefix_len != 0;

    pfx_search:
      while (*pos == ' ' || *pos == '\t')
	pos++;

      auto *space = pos;
      while (*space != '\n' && *space != ' ' && *space != '\t')
	space++;

      if (pos == space)
	// at end of line, nothing here	
	continue;

      if (pfx_search)
	{
	  if (size_t (space - pos) == prefix_len
	      && std::equal (pos, space, prefix))
	    pfx_search = false;
	  pos = space;
	  goto pfx_search;
	}

      std::string module (pos, space);
      while (*space == ' ' || *space == '\t')
	space++;
      std::string file (space, eol);

      if (module[0] == '$')
	{
	  if (module == "$root")
	    set_repo (std::move (file));
	  else
	    return lineno;
	}
      else
	{
	  if (file.empty ())
	    file = GetCMIName (module);
	  add_mapping (std::move (module), std::move (file), force);
	}
    }

  return 0;
}

char const *
module_resolver::GetCMISuffix ()
{
  return "gcm";
}

module_resolver *
module_resolver::ConnectRequest (Cody::Server *s, unsigned version,
				 std::string &a, std::string &i)
{
  if (!version || version > Cody::Version)
    s->ErrorResponse ("version mismatch");
  else if (a != "GCC")
    // Refuse anything but GCC
    ErrorResponse (s, std::string ("only GCC supported"));
  else if (!ident.empty () && ident != i)
    // Failed ident check
    ErrorResponse (s, std::string ("bad ident"));
  else
    // Success!
    s->ConnectResponse ("gcc");

  return this;
}

int
module_resolver::ModuleRepoRequest (Cody::Server *s)
{
  s->PathnameResponse (repo);
  return 0;
}

int
module_resolver::cmi_response (Cody::Server *s, std::string &module)
{
  auto iter = map.find (module);
  if (iter == map.end ())
    {
      std::string file = default_map ? GetCMIName (module) : std::string ();
      auto res = map.emplace (module, file);
      iter = res.first;
    }

  if (iter->second.empty ())
    s->ErrorResponse ("no such module");
  else
    s->PathnameResponse (iter->second);

  return 0;
}

int
module_resolver::ModuleExportRequest (Cody::Server *s, Cody::Flags,
				      std::string &module)
{
  return cmi_response (s, module);
}

int
module_resolver::ModuleImportRequest (Cody::Server *s, Cody::Flags,
				      std::string &module)
{
  return cmi_response (s, module);
}

int
module_resolver::IncludeTranslateRequest (Cody::Server *s, Cody::Flags,
					  std::string &include)
{
  auto iter = map.find (include);
  if (iter == map.end () && default_translate)
    {
      // Not found, look for it
      auto file = GetCMIName (include);
      struct stat statbuf;
      bool ok = true;

#if HAVE_FSTATAT
      int fd_dir = AT_FDCWD;
      if (!repo.empty ())
	{
	  if (fd_repo == -1)
	    {
	      fd_repo = open (repo.c_str (),
			      O_RDONLY | O_CLOEXEC | O_DIRECTORY);
	      if (fd_repo < 0)
		fd_repo = -2;
	    }
	  fd_dir = fd_repo;
	}

      if (!repo.empty () && fd_repo < 0)
	ok = false;
      else if (fstatat (fd_dir, file.c_str (), &statbuf, 0) < 0
	       || !S_ISREG (statbuf.st_mode))
	ok = false;
#else
      auto append = repo;
      append.push_back (DIR_SEPARATOR);
      append.append (file);
      if (stat (append.c_str (), &statbuf) < 0
	  || !S_ISREG (statbuf.st_mode))
	ok = false;
#endif
      if (!ok)
	// Mark as not present
	file.clear ();
      auto res = map.emplace (include, file);
      iter = res.first;
    }

  if (iter == map.end () || iter->second.empty ())
    s->BoolResponse (false);
  else
    s->PathnameResponse (iter->second);

  return 0;
}

/* This handles a client notification to the server that a CMI has been
   produced for a module.  For this simplified server, we just accept
   the transaction and respond with "OK".  */

int
module_resolver::ModuleCompiledRequest (Cody::Server *s, Cody::Flags,
				      std::string &)
{
  s->OKResponse();
  return 0;
}
