/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.felix.gogo.runtime;

public class BaseTokenizer
{

    protected static final char EOT = (char) -1;

    protected final Token text;

    protected short line;
    protected short column;
    protected char ch;
    protected int index;

    public BaseTokenizer(CharSequence text)
    {
        this.text = text instanceof Token ? (Token) text : new Token(text);
        getch();
    }

    public Token text()
    {
        return text;
    }

    protected void find(char target, char deeper)
    {
        final short sLine = line;
        final short sCol = column;
        int level = 1;

        while (level != 0)
        {
            if (eot())
            {
                throw new EOFError(sLine, sCol, "unexpected eof found in the middle of a compound for '"
                        + deeper + target + "'", "compound", Character.toString(target));
                // TODO: fill context correctly
            }

            getch();
            if (ch == '\\')
            {
                escape();
                continue;
            }
            if (ch == target)
            {
                level--;
            }
            else
            {
                if (ch == deeper)
                {
                    level++;
                }
                else
                {
                    if (ch == '"' || ch == '\'' || ch == '`')
                    {
                        skipQuote();
                    }
                }
            }
        }
    }

    protected char escape()
    {
        assert '\\' == ch;
        final short sLine = line;
        final short sCol = column;

        switch (getch())
        {
            case 'u':
                getch();
                int nb = 0;
                for (int i = 0; i < 4; i++)
                {
                    char ch = Character.toUpperCase(this.ch);
                    if (ch >= '0' && ch <= '9')
                    {
                        nb = nb * 16 + (ch - '0');
                        getch();
                        continue;
                    }
                    if (ch >= 'A' && ch <= 'F')
                    {
                        nb = nb * 16 + (ch - 'A' + 10);
                        getch();
                        continue;
                    }
                    if (ch == 0) {
                        throw new EOFError(sLine, sCol, "unexpected EOT in \\ escape", "escape", "0");
                    } else {
                        throw new SyntaxError(sLine, sCol, "bad unicode", text);
                    }
                }
                index--;
                return (char) nb;

            case EOT:
                throw new EOFError(sLine, sCol, "unexpected EOT in \\ escape", "escape", " ");

            case '\n':
                return '\0'; // line continuation

            case '\\':
            case '\'':
            case '"':
            case '$':
                return ch;

            default:
                return ch;
        }
    }

    protected void skipQuote()
    {
        assert '\'' == ch || '"' == ch;
        final char quote = ch;
        final short sLine = line;
        final short sCol = column;

        while (getch() != EOT)
        {
            if (quote == ch)
            {
                return;
            }

            if ((quote == '"') && ('\\' == ch))
                escape();
        }

        throw new EOFError(sLine, sCol, "unexpected EOT looking for matching quote: "
                + quote,
                quote == '"' ? "dquote" : "quote",
                Character.toString(quote));
    }

    protected void skipSpace()
    {
        skipSpace(false);
    }

    protected void skipSpace(boolean skipNewLines)
    {
        while (true)
        {
            while (isBlank(ch))
            {
                getch();
            }

            // skip continuation lines, but not other escapes
            if (('\\' == ch) && (peek() == '\n'))
            {
                getch();
                getch();
                continue;
            }

            if (skipNewLines && ('\n' == ch))
            {
                getch();
                continue;
            }

            if (skipNewLines && ('\r' == ch) && (peek() == '\n'))
            {
                getch();
                getch();
                continue;
            }

            // skip comments
            if (('/' == ch) || ('#' == ch))
            {
                if (('#' == ch) || (peek() == '/'))
                {
                    while ((getch() != EOT) && ('\n' != ch))
                    {
                        //loop
                    }
                    continue;
                }
                else if ('*' == peek())
                {
                    short sLine = line;
                    short sCol = column;
                    getch();

                    while ((getch() != EOT) && !(('*' == ch) && (peek() == '/')))
                    {
                        //loop
                    }

                    if (EOT == ch)
                    {
                        throw new EOFError(sLine, sCol,
                                "unexpected EOT looking for closing comment: */",
                                "comment",
                                "*/");
                    }

                    getch();
                    getch();
                    continue;
                }
            }

            break;
        }
    }

    protected boolean isBlank(char ch)
    {
        return ' ' == ch || '\t' == ch;
    }

    protected boolean eot()
    {
        return index >= text.length();
    }

    protected char getch()
    {
        return ch = getch(false);
    }

    protected char peek()
    {
        return getch(true);
    }

    protected char getch(boolean peek)
    {
        if (eot())
        {
            if (!peek)
            {
                ++index;
                ch = EOT;
            }
            return EOT;
        }

        int current = index;
        char c = text.charAt(index++);

//        if (('\r' == c) && !eot() && (text.charAt(index) == '\n'))
//            c = text.charAt(index++);

        if (peek)
        {
            index = current;
        }
        else if ('\n' == c)
        {
            ++line;
            column = 0;
        }
        else
            ++column;

        return c;
    }

}
