using System;
using System.Collections.Generic;
using System.IO;
using MarketData.Utils;
using StopLimits=MarketData.Generator.Model.StopLimits;

namespace MarketData.Generator.MGSHMomentum
{
// *****************************************************************************
  public class MGSHSessionManager
  {
    private const String SIGNATURE="MGSHSESSIONv2.00";

    public bool SaveSession(MGSHSessionParams sessionParams,String pathSessionFile)
    {
      try
      {
        if(null==pathSessionFile)return false;
        pathSessionFile=GetSessionFileName(pathSessionFile);
        FileStream outStream=new FileStream(pathSessionFile,FileMode.Create);
        StreamWriter streamWriter=new StreamWriter(outStream);
        streamWriter.WriteLine(SIGNATURE);
        streamWriter.WriteLine((new NVP("LastUpdated",sessionParams.LastUpdated.ToString())).ToString());
        streamWriter.WriteLine((new NVP("TradeDate",sessionParams.TradeDate.ToShortDateString())).ToString());
        streamWriter.WriteLine((new NVP("StartDate",sessionParams.StartDate.ToShortDateString())).ToString());
        streamWriter.WriteLine((new NVP("AnalysisDate",sessionParams.AnalysisDate.ToShortDateString())).ToString());
        streamWriter.WriteLine((new NVP("Cycle",sessionParams.Cycle.ToString())).ToString());
        streamWriter.WriteLine((new NVP("CashBalance",sessionParams.CashBalance.ToString())).ToString());
        streamWriter.WriteLine((new NVP("NonTradeableCash",sessionParams.NonTradeableCash.ToString())).ToString());
        streamWriter.WriteLine((new NVP("HedgeCashBalance",sessionParams.HedgeCashBalance.ToString())).ToString());

        NVPCollection configurationCollection=sessionParams.Configuration.ToNVPCollection();
        streamWriter.WriteLine(configurationCollection.ToString());
        List<NVPCollections> nvpCollectionsList=sessionParams.ActivePositions.ToNVPCollections();
        int totalPositions=0;
        foreach(NVPCollections nvpCollections in nvpCollectionsList)
        {
          List<String> nvpCollectionsStringList=nvpCollections.ToList();
          totalPositions+=nvpCollectionsStringList.Count;
        }
        streamWriter.WriteLine((new NVP("TotalActivePositions",totalPositions.ToString())).ToString());
        foreach(NVPCollections nvpCollections in nvpCollectionsList)
        {
          List<String> nvpCollectionsStringList=nvpCollections.ToList();
          foreach(String str in nvpCollectionsStringList)
          {
            streamWriter.WriteLine(str);
          }
        }
        NVPCollections allPositionsCollections=sessionParams.AllPositions.ToNVPCollections();
        List<String> nvpAllCollectionsStringList=allPositionsCollections.ToList();
        streamWriter.WriteLine((new NVP("TotalPositions",nvpAllCollectionsStringList.Count.ToString())).ToString());
        foreach(String str in nvpAllCollectionsStringList)streamWriter.WriteLine(str);

        if(null == sessionParams.StopLimits)sessionParams.StopLimits = new StopLimits();
        NVPCollections allStopLimitsCollections=sessionParams.StopLimits.ToNVPCollections();
        List<String> nvpStopLimitsCollectionsStringList=allStopLimitsCollections.ToList();
        streamWriter.WriteLine((new NVP("TotalStopLimits",nvpStopLimitsCollectionsStringList.Count.ToString())).ToString());
        foreach(String str in nvpStopLimitsCollectionsStringList) streamWriter.WriteLine(str);

        if(null == sessionParams.HedgePositions)sessionParams.HedgePositions = new MGSHPositions();
        NVPCollections hedgePositionsCollections=sessionParams.HedgePositions.ToNVPCollections();
        List<String> nvpHedgePositionsStringList=hedgePositionsCollections.ToList();
        streamWriter.WriteLine((new NVP("TotalHedgePositions",nvpHedgePositionsStringList.Count.ToString())).ToString());
        foreach(String str in nvpHedgePositionsStringList)streamWriter.WriteLine(str);

        NVPCollections pricingExceptionsCollections=sessionParams.PricingExceptions.ToNVPCollections();
        List<String> nvpPricingExceptionsCollectionsStringList=pricingExceptionsCollections.ToList();
        streamWriter.WriteLine((new NVP("TotalPricingExceptions",nvpPricingExceptionsCollectionsStringList.Count.ToString())).ToString());
        foreach(String str in nvpPricingExceptionsCollectionsStringList)streamWriter.WriteLine(str);

        streamWriter.Flush();
        outStream.Flush();
        streamWriter.Close();
        outStream.Close();
        outStream.Dispose();
        return true;
      }
      catch(Exception exception)
      {
        MDTrace.WriteLine(LogLevel.DEBUG,String.Format("{0}",exception.ToString()));
        return false;
      }
    }
    public static MGSHSessionParams RestoreSession(String pathSessionFile)
    {
      FileStream inStream =null;
      StreamReader streamReader=null;
      try
      {
        if(!SessionAvailable(pathSessionFile))return null;
        MGSHSessionParams sessionParams=new MGSHSessionParams();
        inStream =new FileStream(pathSessionFile,FileMode.Open);
        streamReader=new StreamReader(inStream);
        String versionInfo=streamReader.ReadLine();
        double version=double.Parse(Utility.BetweenString(versionInfo,"v",null));
        if(version>2.00)return null;
        NVP lastUpdated=new NVP(streamReader.ReadLine());
        NVP tradeDate=new NVP(streamReader.ReadLine());
        NVP startDate=new NVP(streamReader.ReadLine());
        NVP analysisDate=new NVP(streamReader.ReadLine());
        NVP cycle=new NVP(streamReader.ReadLine());
        NVP cashBalance=new NVP(streamReader.ReadLine());
        NVP nonTradeableCash=new NVP(streamReader.ReadLine());
        NVP hedgeCashBalance=new NVP(streamReader.ReadLine());
        sessionParams.LastUpdated=lastUpdated.Get<DateTime>();
        sessionParams.TradeDate=tradeDate.Get<DateTime>();
        sessionParams.StartDate=startDate.Get<DateTime>();
        sessionParams.AnalysisDate=analysisDate.Get<DateTime>();
        sessionParams.Cycle=cycle.Get<int>();
        sessionParams.CashBalance=cashBalance.Get<double>();
        sessionParams.NonTradeableCash=nonTradeableCash.Get<double>();
        if(2.00==version)sessionParams.HedgeCashBalance=hedgeCashBalance.Get<double>();
        NVPCollection configurationCollection=new NVPCollection(streamReader.ReadLine());
        sessionParams.Configuration=MGSHConfiguration.FromNVPCollection(configurationCollection);
        int totalActivePositions=(new NVP(streamReader.ReadLine())).Get<int>();
        sessionParams.ActivePositions=new MGSHActivePositions();
        for(int positionIndex=0;positionIndex<totalActivePositions;positionIndex++)
        {
          NVPCollection nvpCollection=new NVPCollection(streamReader.ReadLine());
          sessionParams.ActivePositions.AddFromNVPCollection(nvpCollection);
        }
        int totalPositions=(new NVP(streamReader.ReadLine())).Get<int>(); 
        NVPCollections nvpCollections=new NVPCollections(); 
        for(int positionIndex=0;positionIndex<totalPositions;positionIndex++)
        {
          NVPCollection nvpCollection=new NVPCollection(streamReader.ReadLine());
          nvpCollections.Add(nvpCollection);
        }
        sessionParams.AllPositions=MGSHPositions.FromNVPCollections(nvpCollections);

        if(2.00==version)
        {
          // stop limits
          int totalStopLimits=(new NVP(streamReader.ReadLine())).Get<int>();
          sessionParams.StopLimits=new StopLimits();
          for(int stopLimitIndex=0;stopLimitIndex<totalStopLimits;stopLimitIndex++)
          {
            NVPCollection nvpCollection=new NVPCollection(streamReader.ReadLine());
            sessionParams.StopLimits.AddFromNVPCollection(nvpCollection);
          }

          // hedges
          int totalHedgePositions = (new NVP(streamReader.ReadLine())).Get<int>();
          NVPCollections nvpHedgeCollections=new NVPCollections();
          for(int hedgePositionIndex=0;hedgePositionIndex<totalHedgePositions;hedgePositionIndex++)
          {
            NVPCollection nvpCollection=new NVPCollection(streamReader.ReadLine());
            nvpHedgeCollections.Add(nvpCollection);
          }
          sessionParams.HedgePositions=MGSHPositions.FromNVPCollections(nvpHedgeCollections);

          // pricing exceptions
          int totalPricingExceptions = (new NVP(streamReader.ReadLine())).Get<int>();
          NVPCollections nvpPricingExceptionsCollections=new NVPCollections();
          for(int pricingExceptionIndex=0;pricingExceptionIndex<totalPricingExceptions;pricingExceptionIndex++)
          {
            NVPCollection nvpCollection=new NVPCollection(streamReader.ReadLine());
            nvpPricingExceptionsCollections.Add(nvpCollection);
          }
          sessionParams.PricingExceptions=MGSHPricingExceptions.FromNVPCollections(nvpPricingExceptionsCollections);

        }  // version

        inStream.Close();
        inStream.Dispose();
        inStream = null;
        streamReader.Close();
        streamReader.Dispose();
        streamReader = null;
        return sessionParams;
      }
      finally
      {
        if(null!=streamReader)streamReader.Close();
        if(null!=inStream)inStream.Close();
      }
    }
    public static String GetSessionFileName(String pathSessionFile)
    {
      if (null == pathSessionFile) return null;
      String directory = Path.GetDirectoryName(pathSessionFile);
      if ("".Equals(directory)) directory = Directory.GetCurrentDirectory();
      return directory + "\\" + Path.GetFileNameWithoutExtension(pathSessionFile) + ".txt";
    }
    public static bool SessionAvailable(String pathSessionFile)
    {
      return IsValidSessionFile(pathSessionFile);
    }

    public static double GetSessionFileVersion(String pathSessionFile)
    {
      FileStream inStream =null;
      StreamReader streamReader=null;
      try
      {
        if(null==pathSessionFile)return 0.00;
        pathSessionFile=pathSessionFile.ToLower();
        if(!pathSessionFile.EndsWith(".txt"))pathSessionFile+=".txt";
        if(!File.Exists(pathSessionFile))return 0.00;
        inStream =new FileStream(pathSessionFile,FileMode.Open);
        streamReader=new StreamReader(inStream);
        String versionInfo=streamReader.ReadLine();
        double version=double.Parse(Utility.BetweenString(versionInfo,"v",null));
        return version;
      }
      catch(Exception)
      {
         return 0.00;
      }
      finally
      {
        if(null!=streamReader)streamReader.Close();
        if(null!=inStream)inStream.Close();
      }
    }

    public static bool IsValidSessionFile(String pathSessionFile)
    {
      FileStream inStream =null;
      StreamReader streamReader=null;
      try
      {
        if(null==pathSessionFile)return false;
        pathSessionFile=pathSessionFile.ToLower();
        if(!pathSessionFile.EndsWith(".txt"))pathSessionFile+=".txt";
        if(!File.Exists(pathSessionFile))return false;
        inStream =new FileStream(pathSessionFile,FileMode.Open);
        streamReader=new StreamReader(inStream);
        String versionInfo=streamReader.ReadLine();
        double version=double.Parse(Utility.BetweenString(versionInfo,"v",null));
        if(1.00!=version && 2.00!=version)return false;
        return true;
      }
      catch(Exception)
      {
         return false;
      }
      finally
      {
        if(null!=streamReader)streamReader.Close();
        if(null!=inStream)inStream.Close();
      }
    }
  }
}
