/*============================================================================
  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)
    {
    if (this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator)
      {
      extendText(identifier, this->it);
      ++this->it;
      }
    else
      {
      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;

  bool emptyParamTermination = false;

  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;
    if(this->it == this->Tokens.end())
      {
      emptyParamTermination = true;
      }

    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;
      if(this->it == this->Tokens.end())
        {
        emptyParamTermination = true;
        }
      }
    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;
        if(this->it == this->Tokens.end())
          {
          emptyParamTermination = true;
          }
        }
      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)
        {
        if (!pit->empty() && !emptyParamTermination)
          {
          extendResult(result, *pit);
          }
        if (commaIt != commaTokens.end())
          {
          extendText(result, *commaIt);
          }
        else
          {
          break;
          }
        }
      }
    return;
  }

  size_t 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.");
}
