using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using MarketData.Utils;
using MarketData.Generator.Model;

namespace MarketData.Generator.CMTrend
{
  public class CMTSessionParams
  {
    public DateTime LastUpdated { get; set; }
    public DateTime TradeDate { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime AnalysisDate { get; set; }
    public CMTParams CMTParams { get; set; }
    public ActivePositions ActivePositions { get; set; }
    public Positions AllPositions { get; set; }
    public CMTCandidates Candidates { get; set; }
    public CMTPricingExceptions PricingExceptions { get; set; }
    public StopLimits StopLimits { get; set; }
    public double CashBalance { get; set; }
    public double NonTradeableCash{ get; set; }
    public double InitialCash { get; set; }
    // This gets AllPositions+Positions
    public Positions GetCombinedPositions()
    {
      Positions positions=new Positions();
      foreach(Position position in AllPositions) positions.Add(position);
      foreach(Position position in ActivePositions) positions.Add(position);
      return positions;
    }
  }
  // *****************************************************************************
  public static class CMTSessionManager
  {
    public static bool SaveSession(CMTSessionParams 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("CMTSESSIONv1.00");
        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("CashBalance",sessionParams.CashBalance.ToString())).ToString());
        streamWriter.WriteLine((new NVP("NonTradeableCash",sessionParams.NonTradeableCash.ToString())).ToString());
        NVPCollection configurationCollection=sessionParams.CMTParams.ToNVPCollection();
        streamWriter.WriteLine(configurationCollection.ToString());

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

        NVPCollections nvpCollections=sessionParams.ActivePositions.ToNVPCollections();
        List<String> nvpActivePositionsStringList=nvpCollections.ToList();
        streamWriter.WriteLine((new NVP("TotalActivePositions",nvpActivePositionsStringList.Count.ToString())).ToString());
        foreach(String str in nvpActivePositionsStringList) 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);

        NVPCollections allCandidatesCollections=sessionParams.Candidates.ToNVPCollections();
        List<String> nvpSetupsCollectionsStringList=allCandidatesCollections.ToList();
        streamWriter.WriteLine((new NVP("TotalCandidates",nvpSetupsCollectionsStringList.Count.ToString())).ToString());
        foreach(String str in nvpSetupsCollectionsStringList) streamWriter.WriteLine(str);

        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);

        streamWriter.Flush();
        outStream.Flush();
        streamWriter.Close();
        streamWriter.Dispose();
        outStream.Close();
        outStream.Dispose();
        return true;
      }
      catch(Exception exception)
      {
        MDTrace.WriteLine(LogLevel.DEBUG,String.Format("{0}",exception.ToString()));
        return false;
      }
    }
    public static CMTSessionParams RestoreSession(String pathSessionFile)
    {
      FileStream inStream=null;
      StreamReader streamReader=null;
      try
      {
        pathSessionFile=GetSessionFileName(pathSessionFile);
        if(!SessionAvailable(pathSessionFile)) return null;
        CMTSessionParams sessionParams=new CMTSessionParams();
        inStream=new FileStream(pathSessionFile,FileMode.Open);
        streamReader=new StreamReader(inStream);
        String versionInfo=streamReader.ReadLine();
        if(!versionInfo.StartsWith("CMTSESSION")) return null;
        double version=double.Parse(Utility.BetweenString(versionInfo,"v",null));
        if(1.00!=version) 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 cashBalance=new NVP(streamReader.ReadLine());
        NVP nonTradeableCash=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.CashBalance=cashBalance.Get<double>();
        sessionParams.NonTradeableCash=nonTradeableCash.Get<double>();
        NVPCollection configurationCollection=new NVPCollection(streamReader.ReadLine());
        sessionParams.CMTParams=CMTParams.FromNVPCollection(configurationCollection);

        int totalPricingExceptions=(new NVP(streamReader.ReadLine())).Get<int>();
        sessionParams.PricingExceptions=new CMTPricingExceptions();
        for(int pricingExceptionIndex=0;pricingExceptionIndex<totalPricingExceptions;pricingExceptionIndex++)
        {
          NVPCollection nvpCollection=new NVPCollection(streamReader.ReadLine());
          sessionParams.PricingExceptions.AddFromNVPCollection(nvpCollection);
        }

        int totalActivePositions=(new NVP(streamReader.ReadLine())).Get<int>();
        sessionParams.ActivePositions=new ActivePositions();
        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);
        }

        int totalCandidates=(new NVP(streamReader.ReadLine())).Get<int>();
        sessionParams.Candidates=new CMTCandidates();
        for(int setupIndex=0;setupIndex<totalCandidates;setupIndex++)
        {
          NVPCollection nvpCollection=new NVPCollection(streamReader.ReadLine());
          sessionParams.Candidates.AddFromNVPCollection(nvpCollection);
        }

        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);
        }

        sessionParams.AllPositions=Positions.FromNVPCollections(nvpCollections);
        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 bool IsValidSessionFile(String pathSessionFile)
    {
      FileStream inStream=null;
      StreamReader streamReader=null;
      try
      {
        if(null==pathSessionFile) return false;
        pathSessionFile=GetSessionFileName(pathSessionFile);
        if(!File.Exists(pathSessionFile)) return false;
        inStream=new FileStream(pathSessionFile,FileMode.Open);
        streamReader=new StreamReader(inStream);
        String versionInfo=streamReader.ReadLine();
        if(!versionInfo.StartsWith("CMTSESSION")) return false;
        double version=double.Parse(Utility.BetweenString(versionInfo,"v",null));
        if(1.00!=version) return false;
        return true;
      }
      catch(Exception)
      {
        return false;
      }
      finally
      {
        if(null!=streamReader) streamReader.Close();
        if(null!=inStream) inStream.Close();
      }
    }
  }
}

