/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2012 Stephen Kelly <steveire@gmail.com>

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/

#include "cmGeneratorExpressionParser.h"

#include "cmGeneratorExpressionEvaluator.h"

#include "assert.h"

//----------------------------------------------------------------------------
cmGeneratorExpressionParser::cmGeneratorExpressionParser(
                      const std::vector<cmGeneratorExpressionToken> &tokens)
  : Tokens(tokens), NestingLevel(0)
{
}

//----------------------------------------------------------------------------
void cmGeneratorExpressionParser::Parse(
                        std::vector<cmGeneratorExpressionEvaluator*> &result)
{
  it = this->Tokens.begin();

  while (this->it != this->Tokens.end())
    {
    this->ParseContent(result);
    }
}

//----------------------------------------------------------------------------
static void extendText(std::vector<cmGeneratorExpressionEvaluator*> &result,
                  std::vector<cmGeneratorExpressionToken>::const_iterator it)
{
  if (result.size() > 0
      && (*(result.end() - 1))->GetType()
                                  == cmGeneratorExpressionEvaluator::Text)
    {
    TextContent *textContent = static_cast<TextContent*>(*(result.end() - 1));
    textContent->Extend(it->Length);
    }
  else
    {
    TextContent *textContent = new TextContent(it->Content, it->Length);
    result.push_back(textContent);
    }
}

//----------------------------------------------------------------------------
static void extendResult(std::vector<cmGeneratorExpressionEvaluator*> &result,
                const std::vector<cmGeneratorExpressionEvaluator*> &contents)
{
  if (result.size() > 0
      && (*(result.end() - 1))->GetType()
                                  == cmGeneratorExpressionEvaluator::Text
      && (*contents.begin())->GetType()
                                  == cmGeneratorExpressionEvaluator::Text)
  {
    TextContent *textContent = static_cast<TextContent*>(*(result.end() - 1));
    textContent->Extend(
                  static_cast<TextContent*>(*contents.begin())->GetLength());
    delete *contents.begin();
    result.insert(result.end(), contents.begin() + 1, contents.end());
  } else {
    result.insert(result.end(), contents.begin(), contents.end());
  }
}

//----------------------------------------------------------------------------
void cmGeneratorExpressionParser::ParseGeneratorExpression(
                        std::vector<cmGeneratorExpressionEvaluator*> &result)
{
  assert(this->it != this->Tokens.end());
  unsigned int nestedLevel = this->NestingLevel;
  ++this->NestingLevel;

  std::vector<cmGeneratorExpressionToken>::const_iterator startToken
                                                              = this->it - 1;

  std::vector<cmGeneratorExpressionEvaluator*> identifier;
  while(this->it->TokenType != cmGeneratorExpressionToken::EndExpression
      && this->it->TokenType != cmGeneratorExpressionToken::ColonSeparator)
    {
    this->ParseContent(identifier);
    if (this->it == this->Tokens.end())
      {
      break;
      }
    }
  if (identifier.empty())
    {
    // ERROR
    }

  if (this->it != this->Tokens.end() &&
      this->it->TokenType == cmGeneratorExpressionToken::EndExpression)
    {
    GeneratorExpressionContent *content = new GeneratorExpressionContent(
                startToken->Content, this->it->Content
                                    - startToken->Content
                                    + this->it->Length);
    assert(this->it != this->Tokens.end());
    ++this->it;
    --this->NestingLevel;
    content->SetIdentifier(identifier);
    result.push_back(content);
    return;
    }

  std::vector<std::vector<cmGeneratorExpressionEvaluator*> > parameters;
  std::vector<std::vector<cmGeneratorExpressionToken>::const_iterator>
                                                            commaTokens;
  std::vector<cmGeneratorExpressionToken>::const_iterator colonToken;
  if (this->it != this->Tokens.end() &&
      this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator)
    {
    colonToken = this->it;
    parameters.resize(parameters.size() + 1);
    assert(this->it != this->Tokens.end());
    ++this->it;

    while (this->it != this->Tokens.end() &&
           this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator)
      {
      commaTokens.push_back(this->it);
      parameters.resize(parameters.size() + 1);
      assert(this->it != this->Tokens.end());
      ++this->it;
      }
    while (this->it != this->Tokens.end() &&
           this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator)
      {
      extendText(*(parameters.end() - 1), this->it);
      assert(this->it != this->Tokens.end());
      ++this->it;
      }
    while (this->it != this->Tokens.end() &&
           this->it->TokenType != cmGeneratorExpressionToken::EndExpression)
      {
      this->ParseContent(*(parameters.end() - 1));
      if (this->it == this->Tokens.end())
        {
        break;
        }
      while (this->it != this->Tokens.end() &&
             this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator)
        {
        commaTokens.push_back(this->it);
        parameters.resize(parameters.size() + 1);
        assert(this->it != this->Tokens.end());
        ++this->it;
        }
      while (this->it != this->Tokens.end() &&
             this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator)
        {
        extendText(*(parameters.end() - 1), this->it);
        assert(this->it != this->Tokens.end());
        ++this->it;
        }
      }
      if(this->it != this->Tokens.end()
          && this->it->TokenType == cmGeneratorExpressionToken::EndExpression)
        {
        --this->NestingLevel;
        assert(this->it != this->Tokens.end());
        ++this->it;
        }
    }

  if (nestedLevel != this->NestingLevel)
  {
    // There was a '$<' in the text, but no corresponding '>'. Rebuild to
    // treat the '$<' as having been plain text, along with the
    // corresponding : and , tokens that might have been found.
    extendText(result, startToken);
    extendResult(result, identifier);
    if (!parameters.empty())
      {
      extendText(result, colonToken);

      typedef std::vector<cmGeneratorExpressionEvaluator*> EvaluatorVector;
      typedef std::vector<cmGeneratorExpressionToken> TokenVector;
      std::vector<EvaluatorVector>::const_iterator pit = parameters.begin();
      const std::vector<EvaluatorVector>::const_iterator pend =
                                                         parameters.end();
      std::vector<TokenVector::const_iterator>::const_iterator commaIt =
                                                         commaTokens.begin();
      assert(parameters.size() > commaTokens.size());
      for ( ; pit != pend; ++pit, ++commaIt)
        {
        extendResult(result, *pit);
        if (commaIt != commaTokens.end())
          {
          extendText(result, *commaIt);
          }
        else
          {
          break;
          }
        }
      }
    return;
  }

  int contentLength = ((this->it - 1)->Content
                    - startToken->Content)
                    + (this->it - 1)->Length;
  GeneratorExpressionContent *content = new GeneratorExpressionContent(
                            startToken->Content, contentLength);
  content->SetIdentifier(identifier);
  content->SetParameters(parameters);
  result.push_back(content);
}

//----------------------------------------------------------------------------
void cmGeneratorExpressionParser::ParseContent(
                        std::vector<cmGeneratorExpressionEvaluator*> &result)
{
  assert(this->it != this->Tokens.end());
  switch(this->it->TokenType)
    {
    case cmGeneratorExpressionToken::Text:
    {
      if (this->NestingLevel == 0)
        {
        if (result.size() > 0
            && (*(result.end() - 1))->GetType()
                                      == cmGeneratorExpressionEvaluator::Text)
          {
          // A comma in 'plain text' could have split text that should
          // otherwise be continuous. Extend the last text content instead of
          // creating a new one.
          TextContent *textContent =
                              static_cast<TextContent*>(*(result.end() - 1));
          textContent->Extend(this->it->Length);
          assert(this->it != this->Tokens.end());
          ++this->it;
          return;
          }
        }
      cmGeneratorExpressionEvaluator* n = new TextContent(this->it->Content,
                                                          this->it->Length);
      result.push_back(n);
      assert(this->it != this->Tokens.end());
      ++this->it;
      return ;
    }
    case cmGeneratorExpressionToken::BeginExpression:
      assert(this->it != this->Tokens.end());
      ++this->it;
      this->ParseGeneratorExpression(result);
      return;
    case cmGeneratorExpressionToken::EndExpression:
    case cmGeneratorExpressionToken::ColonSeparator:
    case cmGeneratorExpressionToken::CommaSeparator:
      if (this->NestingLevel == 0)
        {
        extendText(result, this->it);
        }
      else
        {
          assert(!"Got unexpected syntax token.");
        }
      assert(this->it != this->Tokens.end());
      ++this->it;
      return;
    }
    assert(!"Unhandled token in generator expression.");
}
