/**
 * Copyright (c) 2006 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *   IBM - Initial API and implementation
 */
package org.eclipse.xsd.ecore;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.eclipse.emf.common.util.URI;


public class NameMangler
{
  public NameMangler()
  {
    super();
  }

  // This behaves like CodeGenUtil.uncapPrefixedName(), which isn't available here,
  // except without the forceDifferent option.
  // The two methods should be kept in synch. 
  //
  public String uncapName(String name)
  {
    if (name.length() == 0)
    {
      return name;
    }
    else
    {
      String lowerName = name.toLowerCase();
      int i;
      for (i = 0; i < name.length(); i++)
      {
        if (name.charAt(i) == lowerName.charAt(i))
        {
          break;
        }
      }
      if (i > 1 && i < name.length() && !Character.isDigit(name.charAt(i)))
      {
        --i;
      }
      return name.substring(0, i).toLowerCase() + name.substring(i);
    }
  }

  protected static final List<String> DOMAINS = Arrays.asList(new String [] { "COM", "com", "ORG", "org" });

  public String qualifiedPackageName(String namespace)
  {
    URI uri = URI.createURI(namespace);
    List<String> parsedName;
    if (uri.isHierarchical())
    {
      String host = uri.host();
      if (host != null && host.startsWith("www."))
      {
        host = host.substring(4);
      }
      parsedName = parseName(host, '.');
      Collections.reverse(parsedName);
      if (!parsedName.isEmpty())
      {
        parsedName.set(0, parsedName.get(0).toLowerCase());
      }

      parsedName.addAll(parseName(uri.trimFileExtension().path(), '/'));
    }
    else
    {
      String opaquePart = uri.opaquePart();
      int index = opaquePart.indexOf(":");
      if (index != -1 && "urn".equalsIgnoreCase(uri.scheme()))
      {
        parsedName = parseName(opaquePart.substring(0, index), '-');
        if (parsedName.size() > 0 && DOMAINS.contains(parsedName.get(parsedName.size() - 1))) 
        {
          Collections.reverse(parsedName);
          parsedName.set(0, parsedName.get(0).toLowerCase());
        }
        parsedName.addAll(parseName(opaquePart.substring(index + 1), '/'));
      }
      else
      {
        parsedName = parseName(opaquePart, '/');
      }
    }

    StringBuffer qualifiedPackageName = new StringBuffer();
    for (String packageName : parsedName)
    {
      if (packageName.length() > 0)
      {
        if (qualifiedPackageName.length() > 0)
        {
          qualifiedPackageName.append('.');
        }
        qualifiedPackageName.append(validName(packageName, false));
      }
    }
    return qualifiedPackageName.toString();
  }

  protected String validName(String name, boolean isUpperCase)
  {
    return validName(name, isUpperCase, "_"); 
  }
  
  protected String validName(String name, boolean isUpperCase, String prefix)
  {
    return validName(name, isUpperCase ? UPPER_CASE : LOWER_CASE, prefix);
  }

  protected static final int UNCHANGED_CASE = 0;
  protected static final int UPPER_CASE = 1;
  protected static final int LOWER_CASE = 2;

  protected String validName(String name, int casing, String prefix)
  {
    List<String> parsedName = parseName(name, '_');
    StringBuffer result = new StringBuffer();
    for (String nameComponent : parsedName)
    {
      if (nameComponent.length() > 0)
      {
        if (result.length() > 0 || casing == UPPER_CASE)
        {
          result.append(Character.toUpperCase(nameComponent.charAt(0)));
          result.append(nameComponent.substring(1));
        }
        else
        {
          result.append(nameComponent);
        }
      }
    }

    return
      result.length() == 0 ?
        prefix :
        Character.isJavaIdentifierStart(result.charAt(0)) ?
          casing == LOWER_CASE ?
            uncapName(result.toString()) :
            result.toString() :
          prefix + result;
  }

  // This behaves like CodeGenUtil.parseName(), which isn't available here,
  // except it also removes invalid indentifier characters.
  // The two methods should be kept in synch. 
  //
  protected List<String> parseName(String sourceName, char separator)
  {
    List<String> result = new ArrayList<String>();
    if (sourceName != null)
    {
      StringBuffer currentWord = new StringBuffer();
      boolean lastIsLower = false;
      for (int index = 0, length = sourceName.length(); index < length; ++index)
      {
        char curChar = sourceName.charAt(index);
        if (!Character.isJavaIdentifierPart(curChar))
        {
          curChar = separator;
        }
        if (Character.isUpperCase(curChar) || (!lastIsLower && Character.isDigit(curChar)) || curChar == separator)
        {
          if (lastIsLower && currentWord.length() > 1 || curChar == separator && currentWord.length() > 0)
          {
            result.add(currentWord.toString());
            currentWord = new StringBuffer();
          }
          lastIsLower = false;
        }
        else
        {
          if (!lastIsLower)
          {
            int currentWordLength = currentWord.length();
            if (currentWordLength > 1)
            {
              char lastChar = currentWord.charAt(--currentWordLength);
              currentWord.setLength(currentWordLength);
              result.add(currentWord.toString());
              currentWord = new StringBuffer();
              currentWord.append(lastChar);
            }
          }
          lastIsLower = true;
        }

        if (curChar != separator)
        {
          currentWord.append(curChar);
        }
      }

      result.add(currentWord.toString());
    }
    return result;
  }

}
