using Lucene.Net.Analysis;
using Lucene.Net.Search;
using Lucene.Net.Util;
using System;
using System.Collections.Generic;

namespace Lucene.Net.QueryParsers.Classic
{
    /*
     * 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> 
    /// A <see cref="QueryParser"/> which constructs queries to search multiple fields.
    /// </summary>
    public class MultiFieldQueryParser : QueryParser
    {
        protected string[] m_fields;
        protected IDictionary<string, float> m_boosts;

        /// <summary> 
        /// Creates a <see cref="MultiFieldQueryParser"/>. Allows passing of a map with term to
        /// Boost, and the boost to apply to each term.
        /// 
        /// <para/>
        /// It will, when <see cref="QueryParserBase.Parse(string)"/> is called, construct a query like this
        /// (assuming the query consists of two terms and you specify the two fields
        /// <c>title</c> and <c>body</c>):
        /// <para/>
        /// 
        /// <code>
        /// (title:term1 body:term1) (title:term2 body:term2)
        /// </code>
        /// 
        /// <para/>
        /// When <see cref="QueryParserBase.DefaultOperator"/> is set to <see cref="QueryParserBase.AND_OPERATOR"/>, the result will be:
        /// <para/>
        /// 
        /// <code>
        /// +(title:term1 body:term1) +(title:term2 body:term2)
        /// </code>
        /// 
        /// <para/>
        /// When you pass a boost (title=>5 body=>10) you can get
        /// <para/>
        /// 
        /// <code>
        /// +(title:term1^5.0 body:term1^10.0) +(title:term2^5.0 body:term2^10.0)
        /// </code>
        /// 
        /// <para/>
        /// In other words, all the query's terms must appear, but it doesn't matter
        /// in what fields they appear.
        /// <para/>
        /// </summary>
        public MultiFieldQueryParser(LuceneVersion matchVersion, string[] fields, Analyzer analyzer, IDictionary<string, float> boosts)
            : this(matchVersion, fields, analyzer)
        {
            this.m_boosts = boosts;
        }

        /// <summary> 
        /// Creates a MultiFieldQueryParser.
        /// 
        /// <para/>
        /// It will, when <see cref="QueryParserBase.Parse(string)"/> is called, construct a query like this
        /// (assuming the query consists of two terms and you specify the two fields
        /// <c>title</c> and <c>body</c>):
        /// <para/>
        /// 
        /// <code>
        /// (title:term1 body:term1) (title:term2 body:term2)
        /// </code>
        /// 
        /// <para/>
        /// When <see cref="QueryParserBase.DefaultOperator"/> is set to <see cref="QueryParserBase.AND_OPERATOR"/>, the result will be:
        /// <para/>
        /// 
        /// <code>
        /// +(title:term1 body:term1) +(title:term2 body:term2)
        /// </code>
        /// 
        /// <para/>
        /// In other words, all the query's terms must appear, but it doesn't matter
        /// in what fields they appear.
        /// <para/>
        /// </summary>
        public MultiFieldQueryParser(LuceneVersion matchVersion, string[] fields, Analyzer analyzer)
            : base(matchVersion, null, analyzer)
        {
            this.m_fields = fields;
        }

        protected internal override Query GetFieldQuery(string field, string queryText, int slop)
        {
            if (field == null)
            {
                IList<BooleanClause> clauses = new List<BooleanClause>();
                for (int i = 0; i < m_fields.Length; i++)
                {
                    Query q = base.GetFieldQuery(m_fields[i], queryText, true);
                    if (q != null)
                    {
                        //If the user passes a map of boosts
                        if (m_boosts != null)
                        {
                            //Get the boost from the map and apply them
                            float boost = m_boosts[m_fields[i]];
                            q.Boost = boost;
                        }
                        ApplySlop(q, slop);
                        clauses.Add(new BooleanClause(q, Occur.SHOULD));
                    }
                }
                if (clauses.Count == 0)
                    // happens for stopwords
                    return null;
                return GetBooleanQuery(clauses, true);
            }
            Query q2 = base.GetFieldQuery(field, queryText, true);
            ApplySlop(q2, slop);
            return q2;
        }

        private void ApplySlop(Query q, int slop)
        {
            if (q is PhraseQuery)
            {
                ((PhraseQuery)q).Slop = slop;
            }
            else if (q is MultiPhraseQuery)
            {
                ((MultiPhraseQuery)q).Slop = slop;
            }
        }

        protected internal override Query GetFieldQuery(string field, string queryText, bool quoted)
        {
            if (field == null)
            {
                IList<BooleanClause> clauses = new List<BooleanClause>();
                for (int i = 0; i < m_fields.Length; i++)
                {
                    Query q = base.GetFieldQuery(m_fields[i], queryText, quoted);
                    if (q != null)
                    {
                        //If the user passes a map of boosts
                        if (m_boosts != null)
                        {
                            //Get the boost from the map and apply them
                            float boost = m_boosts[m_fields[i]];
                            q.Boost = boost;
                        }
                        clauses.Add(new BooleanClause(q, Occur.SHOULD));
                    }
                }
                if (clauses.Count == 0)  // happens for stopwords
                    return null;
                return GetBooleanQuery(clauses, true);
            }
            Query q2 = base.GetFieldQuery(field, queryText, quoted);
            return q2;
        }

        protected internal override Query GetFuzzyQuery(string field, string termStr, float minSimilarity)
        {
            if (field == null)
            {
                IList<BooleanClause> clauses = new List<BooleanClause>();
                for (int i = 0; i < m_fields.Length; i++)
                {
                    clauses.Add(new BooleanClause(GetFuzzyQuery(m_fields[i], termStr, minSimilarity), Occur.SHOULD));
                }
                return GetBooleanQuery(clauses, true);
            }
            return base.GetFuzzyQuery(field, termStr, minSimilarity);
        }

        protected internal override Query GetPrefixQuery(string field, string termStr)
        {
            if (field == null)
            {
                IList<BooleanClause> clauses = new List<BooleanClause>();
                for (int i = 0; i < m_fields.Length; i++)
                {
                    clauses.Add(new BooleanClause(GetPrefixQuery(m_fields[i], termStr), Occur.SHOULD));
                }
                return GetBooleanQuery(clauses, true);
            }
            return base.GetPrefixQuery(field, termStr);
        }

        protected internal override Query GetWildcardQuery(string field, string termStr)
        {
            if (field == null)
            {
                IList<BooleanClause> clauses = new List<BooleanClause>();
                for (int i = 0; i < m_fields.Length; i++)
                {
                    clauses.Add(new BooleanClause(GetWildcardQuery(m_fields[i], termStr), Occur.SHOULD));
                }
                return GetBooleanQuery(clauses, true);
            }
            return base.GetWildcardQuery(field, termStr);
        }


        protected internal override Query GetRangeQuery(string field, string part1, string part2, bool startInclusive, bool endInclusive)
        {
            if (field == null)
            {
                IList<BooleanClause> clauses = new List<BooleanClause>();
                for (int i = 0; i < m_fields.Length; i++)
                {
                    clauses.Add(new BooleanClause(GetRangeQuery(m_fields[i], part1, part2, startInclusive, endInclusive), Occur.SHOULD));
                }
                return GetBooleanQuery(clauses, true);
            }
            return base.GetRangeQuery(field, part1, part2, startInclusive, endInclusive);
        }

        protected internal override Query GetRegexpQuery(string field, string termStr)
        {
            if (field == null)
            {
                IList<BooleanClause> clauses = new List<BooleanClause>();
                for (int i = 0; i < m_fields.Length; i++)
                {
                    clauses.Add(new BooleanClause(GetRegexpQuery(m_fields[i], termStr),
                        Occur.SHOULD));
                }
                return GetBooleanQuery(clauses, true);
            }
            return base.GetRegexpQuery(field, termStr);
        }

        /// <summary> 
        /// Parses a query which searches on the fields specified.
        /// <para/>
        /// If x fields are specified, this effectively constructs:
        /// 
        /// <code>
        /// (field1:query1) (field2:query2) (field3:query3)...(fieldx:queryx)
        /// </code>
        /// 
        /// </summary>
        /// <param name="matchVersion">Lucene version to match; this is passed through to
        /// <see cref="QueryParser"/>.</param>
        /// <param name="queries">Queries strings to parse</param>
        /// <param name="fields">Fields to search on</param>
        /// <param name="analyzer">Analyzer to use</param>
        /// <exception cref="ParseException">if query parsing fails</exception>
        /// <exception cref="ArgumentException">
        /// if the length of the queries array differs from the length of
        /// the fields array
        /// </exception>
        public static Query Parse(LuceneVersion matchVersion, string[] queries, string[] fields, Analyzer analyzer)
        {
            if (queries.Length != fields.Length)
                throw new ArgumentException("queries.length != fields.length");
            BooleanQuery bQuery = new BooleanQuery();
            for (int i = 0; i < fields.Length; i++)
            {
                QueryParser qp = new QueryParser(matchVersion, fields[i], analyzer);
                Query q = qp.Parse(queries[i]);
                if (q != null && (!(q is BooleanQuery) || ((BooleanQuery)q).Clauses.Count > 0))
                {
                    bQuery.Add(q, Occur.SHOULD);
                }
            }
            return bQuery;
        }

        /// <summary> 
        /// Parses a query, searching on the fields specified. Use this if you need
        /// to specify certain fields as required, and others as prohibited.
        /// <para/>
        /// Usage:
        /// <code>
        ///     string[] fields = {&quot;filename&quot;, &quot;contents&quot;, &quot;description&quot;};
        ///     Occur[] flags = {Occur.SHOULD,
        ///         Occur.MUST,
        ///         Occur.MUST_NOT};
        ///     MultiFieldQueryParser.Parse(&quot;query&quot;, fields, flags, analyzer);
        /// </code>
        /// <para/>
        /// The code above would construct a query:
        /// 
        /// <code>
        /// (filename:query) +(contents:query) -(description:query)
        /// </code>
        /// 
        /// </summary>
        /// <param name="matchVersion">Lucene version to match; this is passed through to
        /// <see cref="QueryParser"/>.</param>
        /// <param name="query">Query string to parse</param>
        /// <param name="fields">Fields to search on</param>
        /// <param name="flags">Flags describing the fields</param>
        /// <param name="analyzer">Analyzer to use</param>
        /// <exception cref="ParseException">if query parsing fails</exception>
        /// <exception cref="ArgumentException">
        /// if the length of the fields array differs from the length of
        /// the flags array
        /// </exception>
        public static Query Parse(LuceneVersion matchVersion, string query, string[] fields, Occur[] flags, Analyzer analyzer)
        {
            if (fields.Length != flags.Length)
                throw new ArgumentException("fields.length != flags.length");
            BooleanQuery bQuery = new BooleanQuery();
            for (int i = 0; i < fields.Length; i++)
            {
                QueryParser qp = new QueryParser(matchVersion, fields[i], analyzer);
                Query q = qp.Parse(query);
                if (q != null && (!(q is BooleanQuery) || ((BooleanQuery)q).Clauses.Count > 0))
                {
                    bQuery.Add(q, flags[i]);
                }
            }
            return bQuery;
        }

        /// <summary> 
        /// Parses a query, searching on the fields specified. Use this if you need
        /// to specify certain fields as required, and others as prohibited.
        /// <para/>
        /// Usage:
        /// <code>
        ///     string[] query = {&quot;query1&quot;, &quot;query2&quot;, &quot;query3&quot;};
        ///     string[] fields = {&quot;filename&quot;, &quot;contents&quot;, &quot;description&quot;};
        ///     Occur[] flags = {Occur.SHOULD,
        ///         Occur.MUST,
        ///         Occur.MUST_NOT};
        ///     MultiFieldQueryParser.Parse(query, fields, flags, analyzer);
        /// </code>
        /// <para/>
        /// The code above would construct a query:
        /// 
        /// <code>
        /// (filename:query1) +(contents:query2) -(description:query3)
        /// </code>
        /// 
        /// </summary>
        /// <param name="matchVersion">Lucene version to match; this is passed through to
        /// <see cref="QueryParser"/>.</param>
        /// <param name="queries">Queries string to parse</param>
        /// <param name="fields">Fields to search on</param>
        /// <param name="flags">Flags describing the fields</param>
        /// <param name="analyzer">Analyzer to use</param>
        /// <exception cref="ParseException">if query parsing fails</exception>
        /// <exception cref="ArgumentException">if the length of the queries, fields, and flags array differ</exception>
        public static Query Parse(LuceneVersion matchVersion, string[] queries, string[] fields, Occur[] flags, Analyzer analyzer)
        {
            if (!(queries.Length == fields.Length && queries.Length == flags.Length))
                throw new ArgumentException("queries, fields, and flags array have have different length");
            BooleanQuery bQuery = new BooleanQuery();
            for (int i = 0; i < fields.Length; i++)
            {
                QueryParser qp = new QueryParser(matchVersion, fields[i], analyzer);
                Query q = qp.Parse(queries[i]);
                if (q != null && (!(q is BooleanQuery) || ((BooleanQuery)q).Clauses.Count > 0))
                {
                    bQuery.Add(q, flags[i]);
                }
            }
            return bQuery;
        }
    }
}