/*
 * Copyright 2000-2011 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.intellij.lang.xpath.context.functions;

import com.intellij.lexer.FilterLexer;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import org.intellij.lang.xpath.XPath2TokenTypes;
import org.intellij.lang.xpath.XPathLexer;
import org.intellij.lang.xpath.XPathTokenTypes;
import org.intellij.lang.xpath.psi.XPath2SequenceType;
import org.intellij.lang.xpath.psi.XPath2Type;
import org.intellij.lang.xpath.psi.XPathType;
import org.jetbrains.annotations.Nullable;

import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/*
* Created by IntelliJ IDEA.
* User: sweinreuter
* Date: 14.01.11
*/
public class FunctionDeclarationParsing {
  public static final String FUNCTION_NAMESPACE = "http://www.w3.org/2005/xpath-functions";

  private FunctionDeclarationParsing() {
  }

  public static Pair<String, ? extends Function> parseFuntionDeclaration(String decl) {
    final Lexer lexer = new FilterLexer(XPathLexer.create(true),
            new FilterLexer.SetFilter(TokenSet.create(XPathTokenTypes.WHITESPACE)));
    lexer.start(decl);

    String prefix = "";
    if (lexer.getTokenType() == XPathTokenTypes.EXT_PREFIX) {
      prefix = lexer.getTokenText();
      lexer.advance();
      match(lexer, XPathTokenTypes.COL);
    }

    final String name = match(lexer, XPathTokenTypes.FUNCTION_NAME);
    match(lexer, XPathTokenTypes.LPAREN);

    final List<Parameter> parameters = new ArrayList<Parameter>();
    while (lexer.getTokenType() != XPathTokenTypes.RPAREN) {
      if (lexer.getTokenType() == XPathTokenTypes.DOTDOT) {
        lexer.advance();
        match(lexer, XPathTokenTypes.DOT);

        parameters.add(new Parameter(XPathType.ANY, Parameter.Kind.VARARG));
      } else {
        match(lexer, XPathTokenTypes.DOLLAR);
        match(lexer, XPathTokenTypes.VARIABLE_NAME);

        match(lexer, XPath2TokenTypes.AS);

        final String type = parseType(lexer);

        final XPath2SequenceType.Cardinality indicator = parseCardinality(lexer);

        parameters.add(new Parameter(mapType(type, indicator), Parameter.Kind.REQUIRED));
      }

      if (lexer.getTokenType() == XPathTokenTypes.COMMA) {
        lexer.advance();
      }
    }
    lexer.advance();

    match(lexer, XPath2TokenTypes.AS);

    final String ret = parseType(lexer);
    final XPath2SequenceType.Cardinality indicator = parseCardinality(lexer);

    final XPathType returnType = mapType(ret, indicator);

    return Pair.create(prefix, new FunctionImpl(name, returnType, parameters.toArray(new Parameter[parameters.size()])));
  }

  public static XPathType mapType(String type, XPath2SequenceType.Cardinality c) {
    if ("none".equals(type)) {
      return XPathType.UNKNOWN;
    }

    XPathType r = null;
    if ("numeric".equals(type)) {
      r = XPath2Type.NUMERIC;
    } else if (type.startsWith("xs:")) {
      final String base = type.substring(3);
      r = XPath2Type.fromName(new QName(XPath2Type.XMLSCHEMA_NS, base));
      if (r == null) {
        r = XPathType.fromString(base);
      }
    } else {
      if (type.endsWith("()")) {
        r = XPath2Type.fromName(new QName("", type));
      }
    }

    if (r != null) {
      if (c != null) {
        r = XPath2SequenceType.create(r, c);
      }
      return r;
    }
    return XPathType.fromString(type);
  }

  @Nullable
  public static XPath2SequenceType.Cardinality parseCardinality(Lexer lexer) {
    if (lexer.getTokenType() == XPath2TokenTypes.QUEST) {
      lexer.advance();
      return XPath2SequenceType.Cardinality.OPTIONAL;
    } else if (lexer.getTokenType() == XPathTokenTypes.MULT || lexer.getTokenType() == XPathTokenTypes.STAR) {
      lexer.advance();
      return XPath2SequenceType.Cardinality.ZERO_OR_MORE;
    } else if (lexer.getTokenType() == XPathTokenTypes.PLUS) {
      lexer.advance();
      return XPath2SequenceType.Cardinality.ONE_OR_MORE;
    }
    return null;
  }

  public static String match(Lexer lexer, IElementType token) {
    assert lexer.getTokenType() == token : lexer.getTokenType() + ": " + lexer.getTokenText();
    final String s = lexer.getTokenText();
    lexer.advance();
    return s;
  }

  @Nullable
  public static String parseType(Lexer lexer) {
    String type = parseQName(lexer);
    if (type == null) {
      if (lexer.getTokenType() == XPath2TokenTypes.ITEM || lexer.getTokenType() == XPathTokenTypes.FUNCTION_NAME || lexer.getTokenType() == XPathTokenTypes.NODE_TYPE) {
        type = lexer.getTokenText();
        lexer.advance();
        match(lexer, XPathTokenTypes.LPAREN);
        match(lexer, XPathTokenTypes.RPAREN);
        type += "()";
      } else {
        assert false : "unexpected token: " + lexer.getTokenType();
      }
    }
    return type;
  }

  @Nullable
  public static String parseQName(Lexer lexer) {
    String name;
    if (lexer.getTokenType() == XPathTokenTypes.NCNAME) {
      name = lexer.getTokenText();
      lexer.advance();
      if (lexer.getTokenType() == XPathTokenTypes.COL) {
        lexer.advance();
        assert lexer.getTokenType() == XPathTokenTypes.NCNAME;
        name += (":" + lexer.getTokenText());
        lexer.advance();
      }
    } else {
      name = null;
    }
    return name;
  }

  public static void addFunction(Map<Pair<QName, Integer>, Function> decls, String s) {
    final Pair<String, ? extends Function> pair = parseFuntionDeclaration(s);
    final Function func = pair.second;

    final boolean fn = pair.first.equals("fn") || pair.first.length() == 0;
    final boolean xs = pair.first.equals("xs");
    final Pair<QName, Integer> key = Pair.create(new QName(fn ? FUNCTION_NAMESPACE : (xs ? XPath2Type.XMLSCHEMA_NS : null), func.getName()), func.getParameters().length);
    assert !decls.containsKey(key) : key;

    decls.put(key, func);

    if (fn) {
      decls.put(Pair.create(new QName(null, func.getName()), func.getParameters().length), func);
    }
  }
}