/* Copyright (C) 2021-2023 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 *) malloc (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 ();
}
