﻿/*
 * 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
 *
 *     https://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.Collections.Generic;

namespace Avro.IO.Parsing
{
    /// <summary>
    /// The class that generates a grammar suitable to parse Avro data in JSON
    /// format.
    /// </summary>
    public class JsonGrammarGenerator : ValidatingGrammarGenerator
    {
        /// <summary>
        /// Returns the non-terminal that is the start symbol for the grammar for the
        /// grammar for the given schema <tt>schema</tt>.
        /// </summary>
        public override Symbol Generate(Schema schema)
        {
            return Symbol.NewRoot(Generate(schema, new Dictionary<LitS, Symbol>()));
        }

        /// <summary>
        /// Returns the non-terminal that is the start symbol for grammar of the given
        /// schema <tt>sc</tt>. If there is already an entry for the given schema in the
        /// given map <tt>seen</tt> then that entry is returned. Otherwise a new symbol
        /// is generated and an entry is inserted into the map.
        /// </summary>
        /// <param name="sc">   The schema for which the start symbol is required </param>
        /// <param name="seen"> A map of schema to symbol mapping done so far. </param>
        /// <returns> The start symbol for the schema </returns>
        protected override Symbol Generate(Schema sc, IDictionary<LitS, Symbol> seen)
        {
            switch (sc.Tag)
            {
                case Schema.Type.Null:
                case Schema.Type.Boolean:
                case Schema.Type.Int:
                case Schema.Type.Long:
                case Schema.Type.Float:
                case Schema.Type.Double:
                case Schema.Type.String:
                case Schema.Type.Bytes:
                case Schema.Type.Fixed:
                case Schema.Type.Union:
                    return base.Generate(sc, seen);
                case Schema.Type.Enumeration:
                    return Symbol.NewSeq(new Symbol.EnumLabelsAction(((EnumSchema)sc).Symbols), Symbol.Enum);
                case Schema.Type.Array:
                    return Symbol.NewSeq(
                        Symbol.NewRepeat(Symbol.ArrayEnd, Symbol.ItemEnd, Generate(((ArraySchema)sc).ItemSchema, seen)),
                        Symbol.ArrayStart);
                case Schema.Type.Map:
                    return Symbol.NewSeq(
                        Symbol.NewRepeat(Symbol.MapEnd, Symbol.ItemEnd, Generate(((MapSchema)sc).ValueSchema, seen),
                            Symbol.MapKeyMarker, Symbol.String), Symbol.MapStart);
                case Schema.Type.Record:
                    {
                        LitS wsc = new LitS(sc);
                        if (!seen.TryGetValue(wsc, out Symbol rresult))
                        {
                            Symbol[] production = new Symbol[((RecordSchema)sc).Fields.Count * 3 + 2];
                            rresult = Symbol.NewSeq(production);
                            seen[wsc] = rresult;

                            int i = production.Length;
                            int n = 0;
                            production[--i] = Symbol.RecordStart;
                            foreach (Field f in ((RecordSchema)sc).Fields)
                            {
                                production[--i] = new Symbol.FieldAdjustAction(n, f.Name, f.Aliases);
                                production[--i] = Generate(f.Schema, seen);
                                production[--i] = Symbol.FieldEnd;
                                n++;
                            }

                            production[i - 1] = Symbol.RecordEnd;
                        }

                        return rresult;
                    }
                case Schema.Type.Logical:
                    return Generate((sc as LogicalSchema).BaseSchema, seen);
                default:
                    throw new Exception("Unexpected schema type");
            }
        }
    }
}
