//===- InputBuilder.cpp ---------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <mcld/MC/InputBuilder.h>

#include <mcld/LinkerConfig.h>
#include <mcld/Config/Config.h>
#include <mcld/Support/Path.h>
#include <mcld/MC/InputFactory.h>
#include <mcld/MC/ContextFactory.h>
#include <mcld/Support/MemoryAreaFactory.h>

using namespace mcld;

InputBuilder::InputBuilder(const LinkerConfig& pConfig)
  : m_Config(pConfig),
    m_pCurrentTree(NULL), m_pMove(NULL), m_Root(),
    m_bOwnFactory(true) {

    m_pInputFactory = new InputFactory(MCLD_NUM_OF_INPUTS, pConfig);
    m_pContextFactory = new ContextFactory(MCLD_NUM_OF_INPUTS);
    m_pMemFactory = new MemoryAreaFactory(MCLD_NUM_OF_INPUTS);
}

InputBuilder::InputBuilder(const LinkerConfig& pConfig,
                           InputFactory& pInputFactory,
                           ContextFactory& pContextFactory,
                           MemoryAreaFactory& pMemoryFactory,
                           bool pDelegate)
  : m_Config(pConfig),
    m_pInputFactory(&pInputFactory),
    m_pMemFactory(&pMemoryFactory),
    m_pContextFactory(&pContextFactory),
    m_pCurrentTree(NULL), m_pMove(NULL), m_Root(),
    m_bOwnFactory(pDelegate) {

}

InputBuilder::~InputBuilder()
{
  if (m_bOwnFactory) {
    delete m_pInputFactory;
    delete m_pContextFactory;
    delete m_pMemFactory;
  }
}

Input* InputBuilder::createInput(const std::string& pName,
                                 const sys::fs::Path& pPath,
                                 unsigned int pType,
                                 off_t pFileOffset)
{
  return m_pInputFactory->produce(pName, pPath, pType, pFileOffset);
}

InputTree& InputBuilder::enterGroup()
{
  assert(NULL != m_pCurrentTree && NULL != m_pMove);

  m_pCurrentTree->enterGroup(m_Root, *m_pMove);
  m_pMove->move(m_Root);
  m_ReturnStack.push(m_Root);
  m_pMove = &InputTree::Downward;

  return *m_pCurrentTree;
}

InputTree& InputBuilder::exitGroup()
{
  assert(NULL != m_pCurrentTree && NULL != m_pMove);

  m_Root = m_ReturnStack.top();
  m_ReturnStack.pop();
  m_pMove = &InputTree::Afterward;

  return *m_pCurrentTree;
}

bool InputBuilder::isInGroup() const
{
  return !m_ReturnStack.empty();
}

const InputTree& InputBuilder::getCurrentTree() const
{
  assert(NULL != m_pCurrentTree && NULL != m_pMove);
  return *m_pCurrentTree;
}

InputTree& InputBuilder::getCurrentTree()
{
  assert(NULL != m_pCurrentTree && NULL != m_pMove);
  return *m_pCurrentTree;
}

void InputBuilder::setCurrentTree(InputTree& pInputTree)
{
  m_pCurrentTree = &pInputTree;
  m_Root = m_pCurrentTree->root();
  m_pMove = &InputTree::Downward;
}

bool InputBuilder::setContext(Input& pInput, bool pCheck)
{
  // The object files in an archive have common path. Every object files in an
  // archive needs a individual context. We identify the object files in an
  // archive by its file offset. Their file offsets are not zero.
  LDContext* context = NULL;
  if (0 != pInput.fileOffset() || !pCheck) {
    // pInput is an object in an archive file. Produce a new context in this
    // case.
    context = m_pContextFactory->produce();
  }
  else {
    // Using pInput.path() to avoid from creating context for identical file
    // twice.
    context = m_pContextFactory->produce(pInput.path());
  }

  pInput.setContext(context);
  return true;
}

bool InputBuilder::setMemory(Input& pInput,
                             FileHandle::OpenMode pMode,
                             FileHandle::Permission pPerm)
{
  MemoryArea *memory = m_pMemFactory->produce(pInput.path(), pMode, pPerm);

  if (!memory->handler()->isGood())
    return false;

  pInput.setMemArea(memory);
  return true;
}

bool InputBuilder::setMemory(Input& pInput, void* pMemBuffer, size_t pSize)
{
  MemoryArea *memory = m_pMemFactory->produce(pMemBuffer, pSize);
  pInput.setMemArea(memory);
  return true;
}

const AttrConstraint& InputBuilder::getConstraint() const
{
  return m_Config.attribute().constraint();
}

const AttributeProxy& InputBuilder::getAttributes() const
{
  return m_pInputFactory->attr();
}

AttributeProxy& InputBuilder::getAttributes()
{
  return m_pInputFactory->attr();
}

