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

namespace MarketData.DataAccess
{
// **********************************************************
  public class ETFHoldingsDA
  {
    private ETFHoldingsDA()
    {
    }
    public static List<String> GetETFSymbols()
    {
      MySqlConnection sqlConnection = null;
      MySqlDataReader sqlDataReader = null;
			MySqlCommand sqlCommand=null;
      List<String> etfSymbols=new List<String>();
      String strQuery = null;

      try
      {
        StringBuilder sb = new StringBuilder();
        sqlConnection = SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("market_data"));
        sb.Append("select distinct(etf_symbol) from etfholdings ");
        sb.Append(" order by 1 asc");
        strQuery = sb.ToString();
        sqlCommand = new MySqlCommand(strQuery, sqlConnection);
        sqlCommand.CommandTimeout = SqlUtils.COMMAND_TIMEOUT;
        sqlDataReader = sqlCommand.ExecuteReader();
        while (sqlDataReader.Read())
        {
          etfSymbols.Add(sqlDataReader.GetString(0));
        }
        return etfSymbols;
      }
      catch (Exception exception)
      {
        MDTrace.WriteLine(LogLevel.DEBUG,exception);
        return null;
      }
      finally
      {
				if(null!=sqlCommand)sqlCommand.Dispose();
        if (null != sqlDataReader) sqlDataReader.Close();
        if (null != sqlConnection) sqlConnection.Close();
      }
    }
    private static bool HaveETFHoldings(String etfSymbol)
    {
      MySqlConnection sqlConnection = null;
      MySqlDataReader sqlDataReader = null;
      ETFHoldings etfHoldings = new ETFHoldings(); // new ETFHoldings(etfSymbol);
      String strQuery = null;

      try
      {
        if (null == etfSymbol) return false;
        StringBuilder sb = new StringBuilder();
        sqlConnection = SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("market_data"));
        sb.Append("select count(*) from etfholdings ");
        sb.Append("where etf_symbol='").Append(etfSymbol).Append("'");
        strQuery = sb.ToString();
        MySqlCommand sqlCommand = new MySqlCommand(strQuery, sqlConnection);
        sqlCommand.CommandTimeout = SqlUtils.COMMAND_TIMEOUT;
        sqlDataReader = sqlCommand.ExecuteReader();
        if (!sqlDataReader.Read()) return false;
        int count = sqlDataReader.GetInt32(0);
				sqlCommand.Dispose();
        return count==0?false:true;
      }
      catch (Exception exception)
      {
        MDTrace.WriteLine(LogLevel.DEBUG,exception);
        return false;
      }
      finally
      {
        if (null != sqlDataReader) sqlDataReader.Close();
        if (null != sqlConnection) sqlConnection.Close();
      }
    }
    private static bool DeleteETFHoldings(String etfSymbol,MySqlConnection sqlConnection,MySqlTransaction sqlTransaction)
    {
      String strQuery = null;
      try
      {
        StringBuilder sb = new StringBuilder();
        sb.Append("delete from etfholdings ");
        sb.Append("where etf_symbol='").Append(etfSymbol).Append("'");
        strQuery = sb.ToString();
        MySqlCommand sqlCommand = new MySqlCommand(strQuery, sqlConnection,sqlTransaction);
        sqlCommand.CommandTimeout = SqlUtils.COMMAND_TIMEOUT;
        sqlCommand.ExecuteNonQuery();
				sqlCommand.Dispose();
        return true;
      }
      catch (Exception exception)
      {
        MDTrace.WriteLine(LogLevel.DEBUG,exception);
        return false;
      }
      finally
      {
      }
    }
    public static bool InsertOrUpdate(ETFHoldings etfHoldings)
    {
      MySqlConnection sqlConnection = null;
      MySqlTransaction sqlTransaction = null;
      String strQuery = null;

      try
      {
        if (null == etfHoldings || 0 == etfHoldings.Count) return false;
        sqlConnection = SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("market_data"));
        sqlTransaction = sqlConnection.BeginTransaction(System.Data.IsolationLevel.ReadCommitted);
        List<String> etfSymbols = etfHoldings.GetETFSymbols();
        DateTime modified = DateTime.Now;
        foreach (String etfSymbol in etfSymbols)
        {
          if (HaveETFHoldings(etfSymbol)) DeleteETFHoldings(etfSymbol, sqlConnection, sqlTransaction);
        }
        for (int index = 0; index < etfHoldings.Count; index++)
        {
          ETFHolding etfHolding = etfHoldings[index];
          StringBuilder sb = new StringBuilder();
          sb.Append("insert into ETFHoldings(etf_symbol,holding_symbol,holding_symbol_sc,pcnt_of_assets,company,modified)values(");
          sb.Append(SqlUtils.ToSqlString(etfHolding.ETFSymbol)).Append(",");
          sb.Append(SqlUtils.ToSqlString(etfHolding.HoldingSymbol)).Append(",");
          sb.Append(SqlUtils.ToSqlString(etfHolding.HoldingSymbolShareClass)).Append(",");
          sb.Append(etfHolding.PercentOfAssets).Append(",");
          sb.Append(SqlUtils.ToSqlString(etfHolding.HoldingCompanyName)).Append(",");
          sb.Append(SqlUtils.ToSqlString(Utility.DateTimeToStringYYYYHMMHDD(modified)));
          sb.Append(")");
          strQuery = sb.ToString();
          MySqlCommand sqlCommand = new MySqlCommand(strQuery, sqlConnection, sqlTransaction);
          sqlCommand.CommandTimeout = SqlUtils.COMMAND_TIMEOUT;
          sqlCommand.ExecuteNonQuery();
					sqlCommand.Dispose();
        }
        sqlTransaction.Commit();
        return true;
      }
      catch (Exception exception)
      {
        MDTrace.WriteLine(LogLevel.DEBUG,exception);
        return false;
      }
      finally
      {
        if (null != sqlConnection) sqlConnection.Close();
        if (null != sqlTransaction) sqlTransaction.Dispose();
      }
    }
    public static ETFHoldings GetETFHoldings(String etfSymbol)
    {
      MySqlConnection sqlConnection = null;
      MySqlDataReader sqlDataReader = null;
			MySqlCommand sqlCommand=null;
      ETFHoldings etfHoldings = new ETFHoldings();
      String strQuery = null;

      try
      {
        StringBuilder sb = new StringBuilder();
        sqlConnection = SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("market_data"));
        sb.Append("select etf_symbol,holding_symbol,holding_symbol_sc,pcnt_of_assets,company,modified from etfholdings ");
        sb.Append("where etf_symbol='").Append(etfSymbol).Append("'");
        sb.Append(" order by pcnt_of_assets desc");
        strQuery = sb.ToString();
        sqlCommand = new MySqlCommand(strQuery, sqlConnection);
        sqlCommand.CommandTimeout = SqlUtils.COMMAND_TIMEOUT;
        sqlDataReader = sqlCommand.ExecuteReader();
        while (sqlDataReader.Read())
        {
          ETFHolding etfHolding = new ETFHolding();
          etfHolding.ETFSymbol = sqlDataReader.GetString(0);
          etfHolding.HoldingSymbol = sqlDataReader.GetString(1);
          etfHolding.HoldingSymbolShareClass = sqlDataReader.GetString(2);
          etfHolding.PercentOfAssets = sqlDataReader.GetDouble(3);
          etfHolding.HoldingCompanyName = sqlDataReader.GetString(4);
          etfHolding.Modified = sqlDataReader.GetDateTime(5);
          etfHoldings.Add(etfHolding);
        }
        return etfHoldings;
      }
      catch (Exception exception)
      {
        MDTrace.WriteLine(LogLevel.DEBUG,exception);
        return null;
      }
      finally
      {
				if(null!=sqlCommand)sqlCommand.Dispose();
        if (null != sqlDataReader) sqlDataReader.Close();
        if (null != sqlConnection) sqlConnection.Close();
      }
    }
    public static ETFHoldings GetETFHoldingsWithExposureToSymbolLike(String holdingSymbol)
    {
      MySqlConnection sqlConnection = null;
      MySqlDataReader sqlDataReader = null;
			MySqlCommand sqlCommand=null;
      ETFHoldings etfHoldings = new ETFHoldings();
      String strQuery = null;

      try
      {
        StringBuilder sb = new StringBuilder();
        sqlConnection = SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("market_data"));
        sb.Append("select etf_symbol,holding_symbol,holding_symbol_sc,pcnt_of_assets,company,modified from etfholdings ");
        sb.Append("where holding_symbol like '%").Append(holdingSymbol).Append("%'");
        sb.Append(" order by pcnt_of_assets desc");
        strQuery = sb.ToString();
        sqlCommand = new MySqlCommand(strQuery, sqlConnection);
        sqlCommand.CommandTimeout = SqlUtils.COMMAND_TIMEOUT;
        sqlDataReader = sqlCommand.ExecuteReader();
        while (sqlDataReader.Read())
        {
          ETFHolding etfHolding = new ETFHolding();
          etfHolding.ETFSymbol = sqlDataReader.GetString(0);
          etfHolding.HoldingSymbol = sqlDataReader.GetString(1);
          etfHolding.HoldingSymbolShareClass = sqlDataReader.GetString(2);
          etfHolding.PercentOfAssets = sqlDataReader.GetDouble(3);
          etfHolding.HoldingCompanyName = sqlDataReader.GetString(4);
          etfHolding.Modified = sqlDataReader.GetDateTime(5);
          etfHoldings.Add(etfHolding);
        }
        return etfHoldings;
      }
      catch (Exception exception)
      {
        MDTrace.WriteLine(LogLevel.DEBUG,exception);
        return null;
      }
      finally
      {
				if(null!=sqlCommand)sqlCommand.Dispose();
        if (null != sqlDataReader) sqlDataReader.Close();
        if (null != sqlConnection) sqlConnection.Close();
      }
    }
    public static ETFHoldings GetETFHoldingsWithExposureToCompanyLike(String searchValue)
    {
      MySqlConnection sqlConnection = null;
      MySqlDataReader sqlDataReader = null;
			MySqlCommand sqlCommand=null;
      ETFHoldings etfHoldings = new ETFHoldings();
      String strQuery = null;

      try
      {
        StringBuilder sb = new StringBuilder();
        sqlConnection = SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("market_data"));
        sb.Append("select etf_symbol,holding_symbol,holding_symbol_sc,pcnt_of_assets,company,modified from etfholdings ");
        sb.Append("where company like '%").Append(searchValue).Append("%'");
        sb.Append(" order by pcnt_of_assets desc");
        strQuery = sb.ToString();
        sqlCommand = new MySqlCommand(strQuery, sqlConnection);
        sqlCommand.CommandTimeout = SqlUtils.COMMAND_TIMEOUT;
        sqlDataReader = sqlCommand.ExecuteReader();
        while (sqlDataReader.Read())
        {
          ETFHolding etfHolding = new ETFHolding();
          etfHolding.ETFSymbol = sqlDataReader.GetString(0);
          etfHolding.HoldingSymbol = sqlDataReader.GetString(1);
          etfHolding.HoldingSymbolShareClass = sqlDataReader.GetString(2);
          etfHolding.PercentOfAssets = sqlDataReader.GetDouble(3);
          etfHolding.HoldingCompanyName = sqlDataReader.GetString(4);
          etfHolding.Modified = sqlDataReader.GetDateTime(5);
          etfHoldings.Add(etfHolding);
        }
        return etfHoldings;
      }
      catch (Exception exception)
      {
        MDTrace.WriteLine(LogLevel.DEBUG,exception);
        return null;
      }
      finally
      {
				if(null!=sqlCommand)sqlCommand.Dispose();
        if (null != sqlDataReader) sqlDataReader.Close();
        if (null != sqlConnection) sqlConnection.Close();
      }
    }
  }
}
