/*============================================================================
  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.empty()
      && (*(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.empty()
      && (*(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.empty()
            && (*(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(0 && "Got unexpected syntax token.");
        }
      assert(this->it != this->Tokens.end());
      ++this->it;
      return;
    }
    assert(0 && "Unhandled token in generator expression.");
}
