/*
 * 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.
 */
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Globalization;

namespace Apache.NMS.Selector
{
    /// <summary>
    /// A filter performing a string matching comparison.
    /// </summary>
    public class LikeExpression : BooleanUnaryExpression
    {
        private bool notNot;
        private Regex pattern;

        protected override string ExpressionSymbol
        {
            get { return notNot ? "LIKE" : "NOT LIKE"; }
        }

        public LikeExpression(IExpression left, string like, string escape, bool notNot)
            : base(left)
        {
            this.notNot = notNot;

            bool doEscape = false;
            char escapeChar = '%';

            if(escape != null)
            {
                if(escape.Length != 1)
                {
                    throw new ApplicationException("The ESCAPE string litteral is invalid.  It can only be one character.  Litteral used: " + escape);
                }
                doEscape = true;
                escapeChar = escape[0];
            }

            StringBuilder temp = new StringBuilder();
            StringBuilder regexp = new StringBuilder(like.Length * 2);
            regexp.Append("^"); // The beginning of the input
            for(int c = 0; c < like.Length; c++)
            {
                char ch = like[c];
                if(doEscape && (ch == escapeChar))
                {
                    c++;
                    if(c >= like.Length)
                    {
                        // nothing left to escape...
                        break;
                    }
                    temp.Append(like[c]);
                }
                else if(ch == '%')
                {
                    if(temp.Length > 0)
                    {
                        regexp.Append(Regex.Escape(temp.ToString()));
                        temp.Length = 0;
                    }
                    regexp.Append(".*?"); // Do a non-greedy match 
                }
                else if(c == '_')
                {
                    if(temp.Length > 0)
                    {
                        regexp.Append(Regex.Escape(temp.ToString()));
                        temp.Length = 0;
                    }
                    regexp.Append("."); // match one 
                }
                else
                {
                    temp.Append(ch);
                }
            }
            if(temp.Length > 0)
            {
                regexp.Append(Regex.Escape(temp.ToString()));
            }
            regexp.Append("$"); // The end of the input

            pattern = new Regex(regexp.ToString(), RegexOptions.Singleline | RegexOptions.Compiled);
        }

        public override object Evaluate(MessageEvaluationContext message)
        {
            object rvalue = this.Right.Evaluate(message);

            bool answer = false;
            if(rvalue != null)
            {
                if(rvalue is string)
                {
                    answer = pattern.IsMatch((string)rvalue);
                }
                else
                {
                    //throw new ApplicationException("LIKE can only operate on string identifiers. LIKE attemped on " + rvalue.GetType().ToString());
                }
            }

            return notNot ? answer : !answer;
        }
    }
}
