// CommandLineParser.cpp

#include "StdAfx.h"

#include "CommandLineParser.h"

static bool IsString1PrefixedByString2_NoCase(const wchar_t *u, const char *a)
{
  for (;;)
  {
    char c = *a;
    if (c == 0)
      return true;
    if (MyCharLower_Ascii(c) != MyCharLower_Ascii(*u))
      return false;
    a++;
    u++;
  }
}

namespace NCommandLineParser {

bool SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
{
  dest1.Empty();
  dest2.Empty();
  bool quoteMode = false;
  unsigned i;
  for (i = 0; i < src.Len(); i++)
  {
    wchar_t c = src[i];
    if ((c == L' ' || c == L'\t') && !quoteMode)
    {
      dest2 = src.Ptr(i + 1);
      return i != 0;
    }
    if (c == L'\"')
      quoteMode = !quoteMode;
    else
      dest1 += c;
  }
  return i != 0;
}

void SplitCommandLine(const UString &s, UStringVector &parts)
{
  UString sTemp = s;
  sTemp.Trim();
  parts.Clear();
  for (;;)
  {
    UString s1, s2;
    if (SplitCommandLine(sTemp, s1, s2))
      parts.Add(s1);
    if (s2.IsEmpty())
      break;
    sTemp = s2;
  }
}


static const char *kStopSwitchParsing = "--";

static bool inline IsItSwitchChar(wchar_t c)
{
  return (c == '-');
}

CParser::CParser(unsigned numSwitches):
  _numSwitches(numSwitches),
  _switches(0)
{
  _switches = new CSwitchResult[numSwitches];
}

CParser::~CParser()
{
  delete []_switches;
}


// if (s) contains switch then function updates switch structures
// out: true, if (s) is a switch
bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)
{
  if (s.IsEmpty() || !IsItSwitchChar(s[0]))
    return false;

  unsigned pos = 1;
  unsigned switchIndex = 0;
  int maxLen = -1;
  
  for (unsigned i = 0; i < _numSwitches; i++)
  {
    const char *key = switchForms[i].Key;
    unsigned switchLen = MyStringLen(key);
    if ((int)switchLen <= maxLen || pos + switchLen > s.Len())
      continue;
    if (IsString1PrefixedByString2_NoCase((const wchar_t *)s + pos, key))
    {
      switchIndex = i;
      maxLen = switchLen;
    }
  }

  if (maxLen < 0)
  {
    ErrorMessage = "Unknown switch:";
    return false;
  }

  pos += maxLen;
  
  CSwitchResult &sw = _switches[switchIndex];
  const CSwitchForm &form = switchForms[switchIndex];
  
  if (!form.Multi && sw.ThereIs)
  {
    ErrorMessage = "Multiple instances for switch:";
    return false;
  }

  sw.ThereIs = true;

  int rem = s.Len() - pos;
  if (rem < form.MinLen)
  {
    ErrorMessage = "Too short switch:";
    return false;
  }
  
  sw.WithMinus = false;
  sw.PostCharIndex = -1;
  
  switch (form.Type)
  {
    case NSwitchType::kMinus:
      if (rem != 0)
      {
        sw.WithMinus = (s[pos] == '-');
        if (sw.WithMinus)
          pos++;
      }
      break;
      
    case NSwitchType::kChar:
      if (rem != 0)
      {
        wchar_t c = s[pos];
        if (c <= 0x7F)
        {
          sw.PostCharIndex = FindCharPosInString(form.PostCharSet, (char)c);
          if (sw.PostCharIndex >= 0)
            pos++;
        }
      }
      break;
      
    case NSwitchType::kString:
      sw.PostStrings.Add((const wchar_t *)s + pos);
      return true;
  }
  if (pos != s.Len())
  {
    ErrorMessage = "Too long switch:";
    return false;
  }
  return true;
}

bool CParser::ParseStrings(const CSwitchForm *switchForms, const UStringVector &commandStrings)
{
  ErrorLine.Empty();
  bool stopSwitch = false;
  FOR_VECTOR (i, commandStrings)
  {
    const UString &s = commandStrings[i];
    if (!stopSwitch)
    {
      if (s.IsEqualTo(kStopSwitchParsing))
      {
        stopSwitch = true;
        continue;
      }
      if (!s.IsEmpty() && IsItSwitchChar(s[0]))
      {
        if (ParseString(s, switchForms))
          continue;
        ErrorLine = s;
        return false;
      }
    }
    NonSwitchStrings.Add(s);
  }
  return true;
}

}
