//===============================================================================
// Microsoft patterns & practices
// Web Service Software Factory
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================

using System;
using System.Collections.Generic;
using System.Text;
using Howest.Guidance.DataAccess.CodeGeneration.ObjectModel.Mappings.Enums;
//using Microsoft.Practices.ServiceFactory.SchemaDiscovery.ObjectModel.Base;
using System.Globalization;
using Microsoft.Practices.RecipeFramework.Extensions.CommonHelpers;
using Howest.SchemaDiscovery.DbObjects;

namespace Howest.Guidance.DataAccess.CodeGeneration.ObjectModel.NamingConventions
{
    /// <summary/>
    public static class NamingHelper
    {
        #region Public Implementation
        /// <summary>
        /// Gets the name of the SP.
        /// </summary>
        /// <param name="table">The table.</param>
        /// <param name="spType">Type of the sp.</param>
        /// <returns></returns>
        /*public static string GetSPName(Table table, StoredProcedureType spType)
        {
            switch(spType)
            {
                case StoredProcedureType.Insert:
                    return GetInsertSPName(GetTableName(table));
                case StoredProcedureType.Delete:
                    return GetDeleteSPName(GetTableName(table));
                case StoredProcedureType.Update:
                    return GetUpdateSPName(GetTableName(table));
                case StoredProcedureType.GetByPK:
                    return GetGetByPKSPName(table);
                case StoredProcedureType.GetByFK:
                    return GetGetByFKSPName(table);
                case StoredProcedureType.GetAll:
                    return GetGetAllSPName(GetTableName(table));
                default:
                    return "";
            }
        }*/

        /// <summary>
        /// Gets the name of the SP.
        /// </summary>
        /// <param name="table">The table.</param>
        /// <param name="spType">Type of the sp.</param>
        /// <returns></returns>
       /* public static string GetSPName(string table, StoredProcedureType spType)
        {
            switch(spType)
            {
                case StoredProcedureType.Insert:
                    return GetInsertSPName(table);
                case StoredProcedureType.Delete:
                    return GetDeleteSPName(table);
                case StoredProcedureType.Update:
                    return GetUpdateSPName(table);
                case StoredProcedureType.GetAll:
                    return GetGetAllSPName(table);
                default:
                    return "";
            }
        }*/

        /// <summary>
        /// Cleans the name of the input parameter.
        /// </summary>
        /// <param name="parameterName">Name of the parameter.</param>
        /// <returns></returns>
        public static string GetFieldName(string type)
        {
            string response = type;

            if(!String.IsNullOrEmpty(response))
            {
                response = GetVariableName(response);
				response = string.Format(System.Globalization.CultureInfo.CurrentCulture, "_{0}", response);
                
            }

            return response;
        }

        /// <summary>
        /// Gets the name of the variable.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public static string GetVariableName(string type)
        {
            return GetVariableName(type, false);
        }

        /// <summary>
        /// Gets the name of the variable.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public static string GetVariableName(string type, bool convertToValidIdentifier)
        {
            string response = type;

            if(!String.IsNullOrEmpty(response))
            {
                response = response.Substring(0, 1).ToLower() + response.Substring(1);

                if(convertToValidIdentifier)
                {
                    response = CodeDomHelper.ConvertToValidIdentifier(response);
                }
            }

            return response;
        }


        /// <summary>
        /// Gets the name of the property.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public static string GetPropertyName(string type)
        {
            string response = type;

            if(!String.IsNullOrEmpty(response))
            {
                response = response.Substring(0, 1).ToUpper() + response.Substring(1);
            }

            return response;
        }

        /// <summary>
        /// Gets the name of the db variable.
        /// </summary>
        /// <param name="dbObject">The db object.</param>
        /// <returns></returns>
        public static string GetDbVariableName(string dbObject)
        {
            string response = string.Empty;

            if(!string.IsNullOrEmpty(dbObject))
            {
                //response = GetDbObjectPrefix() + ReplaceDbIllegalCharacters(dbObject);
                response = GetVariableName(dbObject);
                response = ReplaceDbIllegalCharacters(response);
            }

            return response;
        }

        public static string GetMapBetweenPropertyAndDbVariable(string dbObject)
        {
            string response = string.Empty;

            if(!string.IsNullOrEmpty(dbObject))
            {
                response = NamingHelper.CleanInputParameterName(dbObject);
                response = response.Substring(0, 1).ToUpper() + response.Substring(1);
            }

            return response;
        }

        /// <summary>
        /// Replaces the db illegal characters.
        /// </summary>
        /// <param name="dbObject">The db object.</param>
        /// <returns></returns>
        public static string ReplaceDbIllegalCharacters(string dbObject)
        {
            string response = string.Empty;

            if(!string.IsNullOrEmpty(dbObject))
            {
                response = dbObject.Replace("@", string.Empty);
                response = response.Replace(" ", string.Empty);
                response = response.Replace("[", string.Empty);
                response = response.Replace("]", string.Empty);
            }

            return response;
        }

        /// <summary>
        /// Cleans the name of the input parameter.
        /// </summary>
        /// <param name="parameterName">Name of the parameter.</param>
        /// <returns></returns>
        public static string CleanInputParameterName(string parameterName)
        {
            string response = string.Empty;

            if(!string.IsNullOrEmpty(parameterName))
            {
                response = parameterName.Replace(GetDbObjectPrefix(), string.Empty);
            }

            return response;
        }

        /// <summary>
        /// Gets the name of the operation.
        /// </summary>
        /// <param name="operationName">Name of the operation.</param>
        /// <returns></returns>
        public static string GetOperationName(string operationName)
        {
            string response = string.Empty;

            if(!string.IsNullOrEmpty(operationName))
            {
                response = operationName.Replace(" ", string.Empty);
            }

            return response;
        }
        #endregion

        #region Private Implementation

        private static string GetInsertSPName(string table)
        {
            if(!string.IsNullOrEmpty(table))
            {
                return "Insert" + table.Replace(" ", string.Empty);
            }
            else
            {
                return "Insert";
            }
        }

        private static string GetDeleteSPName(string table)
        {
            if(!string.IsNullOrEmpty(table))
            {
                return "Delete" + table.Replace(" ", string.Empty);
            }
            else
            {
                return "Delete";
            }
        }

        private static string GetUpdateSPName(string table)
        {
            if(!string.IsNullOrEmpty(table))
            {
                return "Update" + table.Replace(" ", string.Empty);
            }
            else
            {
                return "Update";
            }
        }

        private static string GetGetAllSPName(string table)
        {
            if(!string.IsNullOrEmpty(table))
            {
                return "GetAllFrom" + table.Replace(" ", string.Empty);
            }
            else
            {
                return "GetAllFrom";
            }
        }

        private static string GetGetByPKSPName(Table table)
        {
            string response = string.Empty;

            if(table != null)
            {
				response = string.Format(CultureInfo.CurrentCulture, "Get{0}", GetTableName(table).Replace(" ", string.Empty));

                foreach(Column column in table.Columns)
                {
                    if(column.IsPrimaryKey)
                    {
                        response += string.Format(CultureInfo.CurrentCulture, "By{0}And", column.Name);
                    }
                }

                if(response.Length > 0)
                {
                    response = response.Substring(0, response.Length - 3);
                }
            }

            //SP Names need to be less than 128 characters
            if(response.Length > 128)
            {
                response = "GetByPK";
            }

            return response;
        }

        private static string GetGetByFKSPName(Table table)
        {
            string response = String.Empty;

            if(table != null)
            {
				response = string.Format(CultureInfo.CurrentCulture, "Get{0}", GetTableName(table).Replace(" ", string.Empty));

                foreach(Column column in table.Columns)
                {
                    if(column.IsForeignKey)
                    {
                        response += string.Format(CultureInfo.CurrentCulture, "By{0}And", column.Name);
                    }
                }

                if(response.Length > 0)
                {
                    response = response.Substring(0, response.Length - 3);
                }
            }

            //SP Names need to be less than 128 characters
            if(response.Length > 128)
            {
                response = "GetByFK";
            }

            return response;
        }

        private static string GetTableName(Table table)
        {
            const string DBO_SCHEMA = "dbo";

            if(string.Compare(table.Schema, DBO_SCHEMA, StringComparison.InvariantCultureIgnoreCase) == 0)
            {
                return table.Name;
            }
            else
            {
                return table.Schema + table.Name;
            }
        }

        private static string GetDbObjectPrefix()
        {
            return "_";
        }

        #endregion
    }
}