﻿using Lucene.Net.Analysis;
using Lucene.Net.Search;
using Lucene.Net.Util;
using System;

namespace Lucene.Net.QueryParsers.Ext
{
    /*
     * 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.
     */

    /// <summary>
    /// The <see cref="ExtendableQueryParser"/> enables arbitrary query parser extension
    /// based on a customizable field naming scheme. The lucene query syntax allows
    /// implicit and explicit field definitions as query prefix followed by a colon
    /// (':') character. The <see cref="ExtendableQueryParser"/> allows to encode extension
    /// keys into the field symbol associated with a registered instance of
    /// <see cref="ParserExtension"/>. A customizable separation character separates the
    /// extension key from the actual field symbol. The <see cref="ExtendableQueryParser"/>
    /// splits (<see cref="Extensions.SplitExtensionField(string, string)"/>) the
    /// extension key from the field symbol and tries to resolve the associated
    /// <see cref="ParserExtension"/>. If the parser can't resolve the key or the field
    /// token does not contain a separation character, <see cref="ExtendableQueryParser"/>
    /// yields the same behavior as its super class <see cref="Classic.QueryParser"/>. Otherwise,
    /// if the key is associated with a <see cref="ParserExtension"/> instance, the parser
    /// builds an instance of <see cref="ExtensionQuery"/> to be processed by
    /// <see cref="ParserExtension.Parse(ExtensionQuery)"/>.If a extension field does not
    /// contain a field part the default field for the query will be used.
    /// <para>
    /// To guarantee that an extension field is processed with its associated
    /// extension, the extension query part must escape any special characters like
    /// '*' or '['. If the extension query contains any whitespace characters, the
    /// extension query part must be enclosed in quotes.
    /// Example ('_' used as separation character):
    /// <pre>
    ///   title_customExt:"Apache Lucene\?" OR content_customExt:prefix\*
    /// </pre>
    /// 
    /// Search on the default field:
    /// <pre>
    ///   _customExt:"Apache Lucene\?" OR _customExt:prefix\*
    /// </pre>
    /// </para>
    /// <para>
    /// The <see cref="ExtendableQueryParser"/> itself does not implement the logic how
    /// field and extension key are separated or ordered. All logic regarding the
    /// extension key and field symbol parsing is located in <see cref="Extensions"/>.
    /// Customized extension schemes should be implemented by sub-classing
    /// <see cref="Extensions"/>.
    /// </para>
    /// <para>
    /// For details about the default encoding scheme see <see cref="Extensions"/>.
    /// </para>
    /// </summary>
    /// <seealso cref="Extensions"/>
    /// <seealso cref="ParserExtension"/>
    /// <seealso cref="ExtensionQuery"/>
    public class ExtendableQueryParser : Classic.QueryParser
    {
        private readonly string defaultField;
        private readonly Extensions extensions;

  
        /// <summary>
        ///  Default empty extensions instance
        /// </summary>
        private static readonly Extensions DEFAULT_EXTENSION = new Extensions();

        /// <summary>
        /// Creates a new <see cref="ExtendableQueryParser"/> instance
        /// </summary>
        /// <param name="matchVersion">the lucene version to use.</param>
        /// <param name="f">the default query field</param>
        /// <param name="a">the analyzer used to find terms in a query string</param>
        public ExtendableQueryParser(LuceneVersion matchVersion, string f, Analyzer a)
            : this(matchVersion, f, a, DEFAULT_EXTENSION)
        {
        }

        /// <summary>
        /// Creates a new <see cref="ExtendableQueryParser"/> instance
        /// </summary>
        /// <param name="matchVersion">the lucene version to use.</param>
        /// <param name="f">the default query field</param>
        /// <param name="a">the analyzer used to find terms in a query string</param>
        /// <param name="ext">the query parser extensions</param>
        public ExtendableQueryParser(LuceneVersion matchVersion, string f, Analyzer a, Extensions ext)
            : base(matchVersion, f, a)
        {
            this.defaultField = f;
            this.extensions = ext;
        }

        /// <summary>
        /// Returns the extension field delimiter character.
        /// </summary>
        /// <returns>the extension field delimiter character.</returns>
        public virtual char ExtensionFieldDelimiter => extensions.ExtensionFieldDelimiter;

        protected internal override Query GetFieldQuery(string field, string queryText, bool quoted)
        {
            Tuple<string, string> splitExtensionField = this.extensions
                .SplitExtensionField(defaultField, field);
            ParserExtension extension = this.extensions
                .GetExtension(splitExtensionField.Item2);
            if (extension != null)
            {
                return extension.Parse(new ExtensionQuery(this, splitExtensionField.Item1,
                    queryText));
            }
            return base.GetFieldQuery(field, queryText, quoted);
        }
    }
}
