using System;
using System.Collections.Generic;
using System.Text;
using MySql.Data.MySqlClient;
using MarketData.MarketDataModel;
using MarketData.Utils;

namespace MarketData.DataAccess
{
  public class StopLimitDA
  {
    private StopLimitDA()
    {
    }
// **********************************************************************************************************************************************************************************
// ****************************************************************************************** S T O P   L I M I T S  ****************************************************************
// **********************************************************************************************************************************************************************************
    public static StopLimits GetStopLimits(String symbol)
    {
      MySqlConnection sqlConnection = null;
      MySqlDataReader sqlDataReader = null;
      MySqlCommand sqlCommand = null;
      String strQuery = null;
      StopLimits stopLimits = new StopLimits();

      try
      {
        StringBuilder sb = new StringBuilder();
        if (null == symbol) return null;
        sqlConnection = SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("portfolio_data"));
        sb.Append("select symbol,stop_limit,shares,stop_type from stoplimits ");
        sb.Append("where symbol='").Append(symbol).Append("'");
        strQuery = sb.ToString();
        sqlCommand = new MySqlCommand(strQuery, sqlConnection);
        sqlCommand.CommandTimeout = SqlUtils.COMMAND_TIMEOUT;
        sqlDataReader = sqlCommand.ExecuteReader();
        while (sqlDataReader.Read())
        {
          StopLimit stopLimit = new StopLimit();
          stopLimit.Symbol = sqlDataReader.GetString(0);
          stopLimit.StopPrice = sqlDataReader.GetDouble(1);
          stopLimit.Shares = sqlDataReader.GetDouble(2);
          stopLimit.StopType = sqlDataReader.GetString(3);
          stopLimits.Add(stopLimit);
        }
        return stopLimits;
      }
      catch (Exception exception)
      {
        MDTrace.WriteLine(LogLevel.DEBUG, exception);
        return stopLimits;
      }
      finally
      {
        if (null != sqlCommand) sqlCommand.Dispose();
        if (null != sqlDataReader) { sqlDataReader.Close(); sqlDataReader.Dispose(); }
        if (null != sqlConnection) sqlConnection.Close();
      }
    }

    public static StopLimit GetStopLimit(String symbol, double shares)
    {
      MySqlConnection sqlConnection = null;
      MySqlDataReader sqlDataReader = null;
      MySqlCommand sqlCommand = null;
      String strQuery = null;

      try
      {
        StringBuilder sb = new StringBuilder();
        if (null == symbol) return null;
        sqlConnection = SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("portfolio_data"));
        sb.Append("select symbol,stop_limit,shares,stop_type from stoplimits ");
        sb.Append("where symbol='").Append(symbol).Append("'");
        sb.Append(" ");
        sb.Append(" and shares=").Append(Utility.FormatNumber(shares, 2));
        strQuery = sb.ToString();
        sqlCommand = new MySqlCommand(strQuery, sqlConnection);
        sqlCommand.CommandTimeout = SqlUtils.COMMAND_TIMEOUT;
        sqlDataReader = sqlCommand.ExecuteReader();
        if (!sqlDataReader.Read()) return null;
        StopLimit stopLimit = new StopLimit();
        stopLimit.Symbol = sqlDataReader.GetString(0);
        stopLimit.StopPrice = sqlDataReader.GetDouble(1);
        stopLimit.Shares = sqlDataReader.GetDouble(2);
        stopLimit.StopType = sqlDataReader.GetString(3);
        return stopLimit;
      } catch (Exception exception)
      {
        MDTrace.WriteLine(LogLevel.DEBUG, exception);
        return null;
      } finally
      {
        if (null != sqlCommand) sqlCommand.Dispose();
        if (null != sqlDataReader) { sqlDataReader.Close(); sqlDataReader.Dispose(); }
        if (null != sqlConnection) sqlConnection.Close();
      }
    }

    public static bool InsertUpdateStopLimit(StopLimit stopLimit)
    {
      if(null==stopLimit || null==stopLimit.Symbol || double.IsNaN(stopLimit.StopPrice))return false;
      if(!HasStopLimit(stopLimit.Symbol,stopLimit.Shares))return InsertStopLimit(stopLimit);
      return UpdateStopLimit(stopLimit);
    }

    private static bool InsertStopLimit(StopLimit stopLimit)
    {
      MySqlConnection sqlConnection=null;
      MySqlTransaction sqlTransaction=null;
      MySqlCommand sqlCommand=null;
      String strQuery=null;

      try
      {
        sqlConnection=SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("portfolio_data"));
        sqlTransaction=sqlConnection.BeginTransaction(System.Data.IsolationLevel.ReadCommitted);
        StringBuilder sb=new StringBuilder();
        sb.Append("insert into stoplimits(symbol,stop_limit,shares,stop_type)values(");
        sb.Append(SqlUtils.AddQuotes(stopLimit.Symbol)).Append(",");
        sb.Append(stopLimit.StopPrice).Append(",");
        sb.Append(stopLimit.Shares).Append(",");
        if(null!=stopLimit.StopType) sb.Append(SqlUtils.AddQuotes(stopLimit.StopType));
        else sb.Append("null");
        sb.Append(")");
        strQuery=sb.ToString();
        sqlCommand=new MySqlCommand(strQuery,sqlConnection,sqlTransaction);
        sqlCommand.CommandTimeout=SqlUtils.COMMAND_TIMEOUT;
        sqlCommand.ExecuteNonQuery();
        sqlTransaction.Commit();
        return true;
      }
      catch(Exception exception)
      {
        MDTrace.WriteLine(LogLevel.DEBUG,exception);
        return false;
      }
      finally
      {
        if(null!=sqlCommand) sqlCommand.Dispose();
        if(null!=sqlTransaction) sqlTransaction.Dispose();
        if(null!=sqlConnection) sqlConnection.Close();
      }
    }

    private static bool UpdateStopLimit(StopLimit stopLimit)
    {
      MySqlConnection sqlConnection=null;
      MySqlTransaction sqlTransaction=null;
      MySqlCommand sqlCommand=null;
      String strQuery=null;

      try
      {
        sqlConnection=SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("portfolio_data"));
        sqlTransaction=sqlConnection.BeginTransaction(System.Data.IsolationLevel.ReadCommitted);
        StringBuilder sb=new StringBuilder();
        sb.Append("update stoplimits ");
        sb.Append("set ");
        if(null!=stopLimit.StopType) sb.Append("stop_type=").Append(SqlUtils.AddQuotes(stopLimit.StopType)).Append(", ");
        sb.Append("stop_limit=").Append(stopLimit.StopPrice).Append(", ");
        sb.Append("shares=").Append(stopLimit.Shares);
        sb.Append(" where symbol=").Append(SqlUtils.AddQuotes(stopLimit.Symbol));
        sb.Append(" and shares=").Append(Utility.FormatNumber(stopLimit.Shares,2));
        strQuery=sb.ToString();
        sqlCommand=new MySqlCommand(strQuery,sqlConnection,sqlTransaction);
        sqlCommand.CommandTimeout=SqlUtils.COMMAND_TIMEOUT;
        sqlCommand.ExecuteNonQuery();
        sqlTransaction.Commit();
        return true;
      }
      catch(Exception exception)
      {
        MDTrace.WriteLine(LogLevel.DEBUG,exception);
        return false;
      }
      finally
      {
        if(null!=sqlCommand) sqlCommand.Dispose();
        if(null!=sqlConnection) sqlConnection.Close();
        if(null!=sqlTransaction) sqlTransaction.Dispose();
      }
    }

     public static Dictionary<String,bool> HasStopLimit(List<String> symbols)
     {
        MySqlConnection sqlConnection=null;
        MySqlDataReader sqlDataReader=null;
        MySqlCommand sqlCommand=null;
        Dictionary<String,bool> hasStopLimit = new Dictionary<String,bool>();

        try
        {
          if(null == symbols || 0==symbols.Count)return hasStopLimit;
          StringBuilder sb=new StringBuilder();
          if(null==symbols) return null;
          sqlConnection=SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("portfolio_data"));
          sb.Append("select symbol, count(*) from stoplimits ");
          sb.Append("where symbol in ");
          sb.Append(SqlUtils.CreateInClause(symbols));
          sb.Append(" group by 1");
          String strQuery=sb.ToString();
          sqlCommand=new MySqlCommand(strQuery,sqlConnection);
          sqlCommand.CommandTimeout=SqlUtils.COMMAND_TIMEOUT;
          sqlDataReader=sqlCommand.ExecuteReader();
          while(sqlDataReader.Read())
          {
            String symbol = sqlDataReader.GetString(0);
            symbol = symbol.ToUpper();
            hasStopLimit.Add(symbol, true);
          }
          return hasStopLimit;
        }
        catch(Exception exception)
        {
          MDTrace.WriteLine(LogLevel.DEBUG,exception);
          return null;
        }
        finally
        {
          if(null!=sqlCommand) sqlCommand.Dispose();
        if (null != sqlDataReader) {sqlDataReader.Close();sqlDataReader.Dispose();}
          if(null!=sqlConnection) sqlConnection.Close();
        }
     }

    public static bool HasStopLimit(String symbol,double shares)
    {
      MySqlConnection sqlConnection=null;
      MySqlDataReader sqlDataReader=null;
      MySqlCommand sqlCommand=null;
      String strQuery=null;

      try
      {
        StringBuilder sb=new StringBuilder();
        if(null==symbol) return false;
        sqlConnection=SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("portfolio_data"));
        sb.Append("select count(*) from stoplimits ");
        sb.Append("where symbol='").Append(symbol).Append("'");
        sb.Append(" and ");
        sb.Append("shares=").Append(Utility.FormatNumber(shares,2));
        strQuery=sb.ToString();
        sqlCommand=new MySqlCommand(strQuery,sqlConnection);
        sqlCommand.CommandTimeout=SqlUtils.COMMAND_TIMEOUT;
        sqlDataReader=sqlCommand.ExecuteReader();
        if(!sqlDataReader.Read()) return false;
        int count=sqlDataReader.GetInt32(0);
        return count>0?true:false;
      }
      catch(Exception exception)
      {
        MDTrace.WriteLine(LogLevel.DEBUG,exception);
        return false;
      }
      finally
      {
        if(null!=sqlCommand) sqlCommand.Dispose();
        if (null != sqlDataReader) {sqlDataReader.Close();sqlDataReader.Dispose();}
        if(null!=sqlConnection) sqlConnection.Close();
      }
    }

    public static bool DeleteStopLimit(String symbol,double shares)
    {
      MySqlConnection sqlConnection = null;
      MySqlCommand sqlCommand = null;
      String strQuery = null;

      try
      {
        StringBuilder sb = new StringBuilder();
        if (null == symbol) return false;
        sqlConnection = SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("portfolio_data"));
        sb.Append("delete from stoplimits ");
        sb.Append("where symbol='").Append(symbol).Append("'");
        sb.Append(" ");
        sb.Append("and shares=").Append(Utility.FormatNumber(shares,3));
        strQuery = sb.ToString();
        sqlCommand = new MySqlCommand(strQuery, sqlConnection);
        sqlCommand.CommandTimeout = SqlUtils.COMMAND_TIMEOUT;
        sqlCommand.ExecuteNonQuery();
        return true;
      }
      catch (Exception exception)
      {
        MDTrace.WriteLine(LogLevel.DEBUG, exception);
        return false;
      }
      finally
      {
        if (null != sqlCommand) sqlCommand.Dispose();
        if (null != sqlConnection) sqlConnection.Close();
      }
    }
  }
}
