/*
 * 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.Globalization;

namespace Apache.NMS.Selector
{
    /// <summary>
    /// Represents a constant expression.
    /// </summary>
    public class ConstantExpression : IExpression
    {
        private object value;
        public object Value
        {
            get { return value; }
        }    

        public ConstantExpression(object value)
        {
            this.value = value;
        }

        public static ConstantExpression CreateFromDecimal(string text)
        {
    	    // Long integer specified ?
    	    object value;
            if(text.EndsWith("l") || text.EndsWith("L"))
            {
    		    text = text.Substring(0, text.Length - 1);
                value = Int64.Parse(text, CultureInfo.InvariantCulture);
            }
            else
            {
                long lvalue = Int64.Parse(text, CultureInfo.InvariantCulture);
                if(lvalue >= Int32.MinValue && lvalue <= Int32.MaxValue)
                {
                    value = (int)lvalue;
                }
                else
                {
                    value = lvalue;
                }
            }
            return new ConstantExpression(value);
        }

        public static ConstantExpression CreateFromHex(string text)
        {
            long lvalue = Convert.ToInt64(text.Substring(2), 16);

    	    object value;
            if(lvalue >= Int32.MinValue && lvalue <= Int32.MaxValue)
            {
                value = (int)lvalue;
            }
            else
            {
                value = lvalue;
            }
            return new ConstantExpression(value);
        }


        public static ConstantExpression CreateFromOctal(string text)
        {
            long lvalue = Convert.ToInt64(text, 8);

    	    object value;
            if(lvalue >= Int32.MinValue && lvalue <= Int32.MaxValue)
            {
                value = (int)lvalue;
            }
            else
            {
                value = lvalue;
            }
            return new ConstantExpression(value);
        }

        public static ConstantExpression CreateFloat(string text)
        {
            double value = Double.Parse(text, CultureInfo.InvariantCulture);
            return new ConstantExpression(value);
        }

        public object Evaluate(MessageEvaluationContext message)
        {
            return value;
        }

        public override string ToString()
        {
            if(value == null)
            {
                return "NULL";
            }
            if(value is bool)
            {
                return (bool)value ? "TRUE" : "FALSE";
            }
            if(value is string)
            {
                return EncodeString((string)value);
            }
            return value.ToString();
        }

        public override int GetHashCode()
        {
            return (value == null ? 0 : value.GetHashCode());
        }

        /// <summary>
        /// Encodes the value of string so that it looks like it would look like
        /// when it was provided in a selector.
        /// </summary>
        /// <param name="s">String to be encoded.</param>
        /// <return>Encoded string.</return>
        public static string EncodeString(string s)
        {
            StringBuilder b = new StringBuilder();
            b.Append('\'');
            for(int c = 0; c < s.Length; c++)
            {
                char ch = s[c];
                if(ch == '\'')
                {
                    b.Append(ch);
                }
                b.Append(ch);
            }
            b.Append('\'');
            return b.ToString();
        }

        public static readonly BooleanConstantExpression NULL  = new BooleanConstantExpression(null);
        public static readonly BooleanConstantExpression TRUE  = new BooleanConstantExpression(true);
        public static readonly BooleanConstantExpression FALSE = new BooleanConstantExpression(false);
    }
}