using System;
using System.Data;
using System.Diagnostics.CodeAnalysis;
using JetBrains.Annotations;

namespace SDA.DataProvider.Core
{
    public abstract class SDACommandWrapper : IDbCommand
    {
        [CanBeNull]
        public abstract SDAConnectionWrapper Connection { get; set; }

        [CanBeNull]
        public abstract SDATransactionWrapper Transaction { get; set; }

        [NotNull]
        public abstract SDADataReaderWrapper ExecuteReader();

        [NotNull]
        public abstract SDADataReaderWrapper ExecuteReader(CommandBehavior commandBehavior);

        [NotNull]
        public abstract SDACommandParameterCollectionWrapper Parameters { get; }

        [NotNull]
        protected abstract IDbCommand WrappedCommand { get; }

        #region IDisposable Members

        bool _disposed;

        protected virtual void Dispose(bool disposing)
        {
            if (_disposed)
            {
                return;
            }
            _disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        #endregion

        #region IDbCommand Members

        [SuppressMessage("Microsoft.Security", "CA2100:Review SQL queries for security vulnerabilities")]
        [CanBeNull]
        public virtual string CommandText
        {
            get
            {
                return WrappedCommand.CommandText;
            }
            set
            {
                WrappedCommand.CommandText = value;
            }
        }

        public virtual int CommandTimeout
        {
            get
            {
                return WrappedCommand.CommandTimeout;
            }
            set
            {
                WrappedCommand.CommandTimeout = value;
            }
        }

        public virtual CommandType CommandType
        {
            get
            {
                return WrappedCommand.CommandType;
            }
            set
            {
                WrappedCommand.CommandType = value;
            }
        }

        [CanBeNull]
        IDbConnection IDbCommand.Connection
        {
            get
            {
                return Connection;
            }
            set
            {
                Connection = (SDAConnectionWrapper)value;
            }
        }

        [NotNull]
        IDataParameterCollection IDbCommand.Parameters
        {
            get
            {
                throw new NotSupportedException();
            }
        }

        [CanBeNull]
        IDbTransaction IDbCommand.Transaction
        {
            get
            {
                return Transaction;
            }
            set
            {
                Transaction = (SDATransactionWrapper)value;
            }
        }

        public virtual UpdateRowSource UpdatedRowSource
        {
            get
            {
                return WrappedCommand.UpdatedRowSource;
            }
            set
            {
                WrappedCommand.UpdatedRowSource = value;
            }
        }

        public virtual void Cancel()
        {
            WrappedCommand.Cancel();
        }

        public virtual IDbDataParameter CreateParameter()
        {
            return WrappedCommand.CreateParameter();
        }

        public abstract int ExecuteNonQuery();

        IDataReader IDbCommand.ExecuteReader()
        {
            return ExecuteReader();
        }

        IDataReader IDbCommand.ExecuteReader(CommandBehavior behavior)
        {
            return ExecuteReader(behavior);
        }

        public abstract object ExecuteScalar();

        public virtual void Prepare()
        {
            WrappedCommand.Prepare();
        }

        #endregion
    }
}