/*
 *    The contents of this file are subject to the Initial
 *    Developer's Public License Version 1.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://github.com/FirebirdSQL/NETProvider/blob/master/license.txt.
 *
 *    Software distributed under the License is distributed on
 *    an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
 *    express or implied. See the License for the specific
 *    language governing rights and limitations under the License.
 *
 *    All Rights Reserved.
 */

//$Authors = Jiri Cincura (jiri@cincura.net)

using System;
using System.Collections.Generic;
using System.Data.Entity.Core.Metadata.Edm;

namespace EntityFramework.Firebird.SqlGen
{
	internal class Symbol : ISqlFragment
	{
		#region Fields

		private Dictionary<string, Symbol> _columns = new Dictionary<string, Symbol>(StringComparer.CurrentCultureIgnoreCase);
		private bool _needsRenaming = false;
		private bool _isUnnest = false;
		private string _name;
		private string _newName;
		private TypeUsage _type;

		#endregion

		#region Public Properties

		public string Name
		{
			get { return _name; }
		}

		public string NewName
		{
			get { return _newName; }
			set { _newName = value; }
		}

		#endregion

		#region Internal Properties

		internal Dictionary<string, Symbol> Columns
		{
			get { return _columns; }
		}

		internal bool NeedsRenaming
		{
			get { return _needsRenaming; }
			set { _needsRenaming = value; }
		}

		internal bool IsUnnest
		{
			get { return _isUnnest; }
			set { _isUnnest = value; }
		}

		internal TypeUsage Type
		{
			get { return _type; }
			set { _type = value; }
		}

		#endregion

		#region Constructors

		public Symbol(string name, TypeUsage type)
		{
			_name = name;
			_newName = name;
			Type = type;
		}

		#endregion

		#region ISqlFragment Members

		/// <summary>
		/// Write this symbol out as a string for sql.  This is just
		/// the new name of the symbol (which could be the same as the old name).
		///
		/// We rename columns here if necessary.
		/// </summary>
		/// <param name="writer"></param>
		/// <param name="sqlGenerator"></param>
		public void WriteSql(SqlWriter writer, SqlGenerator sqlGenerator)
		{
			if (NeedsRenaming)
			{
				string newName;
				var i = sqlGenerator.AllColumnNames[NewName];
				do
				{
					++i;
					newName = Name + i.ToString(System.Globalization.CultureInfo.InvariantCulture);
				} while (sqlGenerator.AllColumnNames.ContainsKey(newName));
				sqlGenerator.AllColumnNames[NewName] = i;

				// Prevent it from being renamed repeatedly.
				NeedsRenaming = false;
				NewName = newName;

				// Add this column name to list of known names so that there are no subsequent
				// collisions
				sqlGenerator.AllColumnNames[newName] = 0;
			}

			writer.Write(SqlGenerator.QuoteIdentifier(NewName));
		}

		#endregion
	}
}
