/* Copyright (C) 2021-2025 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   This program 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.

   This program 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 this program; if not, write to the Free Software
   Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "config.h"
#include <unistd.h>

#include "util.h"
#include "DbeSession.h"
#include "Function.h"
#include "SourceFile.h"
#include "DefaultMap.h"
#include "DbeFile.h"
#include "LoadObject.h"
#include "Module.h"

int SourceFile::curId = 0;

SourceFile::SourceFile (const char *file_name)
{
  status = OS_NOTREAD;
  srcLines = NULL;
  srcInode = -1;
  lines = NULL;
  dbeLines = NULL;
  functions = new DefaultMap<Function *, Function *>();
  dbeFile = new DbeFile (file_name);
  dbeFile->filetype |= DbeFile::F_SOURCE | DbeFile::F_FILE;
  set_name ((char *) file_name);
  srcMTime = (time_t) 0;
  isTmpFile = false;
  flags = 0;
  read_stabs = false;
  id = (uint64_t) ((Histable::SOURCEFILE << 24) + curId) << 32;
  curId++;
}

SourceFile::~SourceFile ()
{
  destroy_map (DbeLine *, dbeLines);
  delete functions;
  delete dbeFile;
  if (lines)
    {
      lines->destroy ();
      delete lines;
    }
  if (srcLines)
    {
      free (srcLines->get (0));
      delete srcLines;
    }
  if (isTmpFile)
    unlink (name);
}

void
SourceFile::set_name (char* _name)
{
  name = dbe_strdup (_name);
}

char*
SourceFile::get_name (NameFormat)
{
  return name;
}

bool
SourceFile::readSource ()
{
  if (srcLines)
    return true;
  status = OS_NOSRC;
  char *location = dbeFile->get_location ();
  if (location == NULL)
    return false;
  if (!isTmpFile)
    srcMTime = dbeFile->sbuf.st_mtime;
  srcInode = dbeFile->sbuf.st_ino;
  size_t srcLen = dbeFile->sbuf.st_size;
  int fd = open64 (location, O_RDONLY);
  if (fd == -1)
    {
      status = OS_NOSRC;
      return false;
    }
  char *srcMap = (char *) xmalloc (srcLen + 1);
  int64_t sz = read_from_file (fd, srcMap, srcLen);
  if (sz != (int64_t) srcLen)
    append_msg (CMSG_ERROR, GTXT ("%s: Can read only %lld bytes instead %lld"),
		location, (long long) sz, (long long) srcLen);
  srcMap[sz] = 0;
  close (fd);

  // Count the number of lines in the file, converting <nl> to zero
  srcLines = new Vector<char*>();
  srcLines->append (srcMap);
  for (int64_t i = 0; i < sz; i++)
    {
      if (srcMap[i] == '\r')
	{ // Window style
	  srcMap[i] = 0;
	  if (i + 1 < sz && srcMap[i + 1] != '\n')
	    srcLines->append (srcMap + i + 1);
	}
      else if (srcMap[i] == '\n')
	{
	  srcMap[i] = '\0';
	  if (i + 1 < sz)
	    srcLines->append (srcMap + i + 1);
	}
    }
  if (dbeLines)
    {
      Vector<DbeLine *> *v = dbeLines->values ();
      for (long i = 0, sz1 = v ? v->size () : 0; i < sz1; i++)
	{
	  DbeLine *p = v->get (i);
	  if (p->lineno >= srcLines->size ())
	    append_msg (CMSG_ERROR, GTXT ("Wrong line number %d. '%s' has only %d lines"),
			(int) p->lineno, dbeFile->get_location (),
			(int) srcLines->size ());
	}
      delete v;
    }
  status = OS_OK;
  return true;
}

char *
SourceFile::getLine (int lineno)
{
  assert (srcLines != NULL);
  if (lineno > 0 && lineno <= srcLines->size ())
    return srcLines->get (lineno - 1);
  return NTXT ("");
}

DbeLine *
SourceFile::find_dbeline (Function *func, int lineno)
{
  if (lineno < 0 || (lineno == 0 && func == NULL))
    return NULL;
  DbeLine *dbeLine = NULL;
  if (lines)
    { // the source is available
      if (lineno > lines->size ())
	{
	  if (dbeLines)
	    dbeLine = dbeLines->get (lineno);
	  if (dbeLine == NULL)
	    append_msg (CMSG_ERROR,
			GTXT ("Wrong line number %d. '%s' has only %d lines"),
			(int) lineno, dbeFile->get_location (),
			(int) lines->size ());
	}
      else
	{
	  dbeLine = lines->fetch (lineno);
	  if (dbeLine == NULL)
	    {
	      dbeLine = new DbeLine (NULL, this, lineno);
	      lines->store (lineno, dbeLine);
	    }
	}
    }
  if (dbeLine == NULL)
    { // the source is not yet read or lineno is wrong
      if (dbeLines == NULL)
	dbeLines = new DefaultMap<int, DbeLine *>();
      dbeLine = dbeLines->get (lineno);
      if (dbeLine == NULL)
	{
	  dbeLine = new DbeLine (NULL, this, lineno);
	  dbeLines->put (lineno, dbeLine);
	}
    }

  for (DbeLine *last = dbeLine;; last = last->dbeline_func_next)
    {
      if (last->func == func)
	return last;
      if (last->dbeline_func_next == NULL)
	{
	  DbeLine *dl = new DbeLine (func, this, lineno);
	  if (functions->get (func) == NULL)
	    functions->put (func, func);
	  last->dbeline_func_next = dl;
	  dl->dbeline_base = dbeLine;
	  return dl;
	}
    }
}

Vector<Function *> *
SourceFile::get_functions ()
{
  if (!read_stabs)
    {
      // Create all DbeLines for this Source
      read_stabs = true;
      Vector<LoadObject *> *lobjs = dbeSession->get_LoadObjects ();
      for (long i = 0, sz = VecSize (lobjs); i < sz; i++)
	{
	  LoadObject *lo = lobjs->get (i);
	  for (long i1 = 0, sz1 = VecSize (lo->seg_modules); i1 < sz1; i1++)
	    {
	      Module *mod = lo->seg_modules->get (i1);
	      mod->read_stabs ();
	    }
	}
    }
  return functions->keySet ();
}
