using System;
using System.IO;
using MarketData.DataAccess;
using MarketData.MarketDataModel;
using MarketData.Numerical;
using System.Drawing;
using System.Collections.Generic;
using MarketData.Utils;
using System.Threading.Tasks;
using System.Text;

namespace MarketData.CNNProcessing
{
  public class CNNProcessor
	{
	  private CNNProcessor()
		{
		}
	  public static void GenerateTraining()
		{
   	   TestCases testCases=new TestCases();			
			 DataProcessor dataProcessor=new DataProcessor();
			 dataProcessor.Width=128;
			 dataProcessor.Height=128;
			 int dayCount=270;
//			 dataProcessor.UseGrayScale=true;
//			 dataProcessor.PenWidth=1;

			dataProcessor.PenWidthArray=new float[]{.50f,.75f,1.00f,1.12f,1.25f,1.31f,1.37f,1.50f,1.56f,1.62f,1.75f,1.87f,2.00f};
//			dataProcessor.PenWidthArray=new float[]{.50f,.625f,.75f,.875f,1.00f,1.06f,1.12f,1.185f,1.25f,1.28f,1.31f,1.37f,1.435f,1.50f,1.56f,1.59f,1.62f,1.685f,1.75f,1.87f,1.935f,2.00f};
//      dataProcessor.PenWidthArray=new float[]{0.550000f,0.600000f,0.650000f,0.700000f,0.750000f,0.800000f,0.850000f,0.900000f,0.950000f,1.000000f,1.050000f,1.100000f,1.150000f,1.200000f,1.250000f,1.300000f,1.350000f,1.400000f,1.450000f,1.500000f,1.550000f,1.600000f,1.650000f,1.700000f,1.750000f,1.800000f,1.850000f,1.900000f,1.950000f,2.000000f}
//      dataProcessor.PenWidthArray=new float[]{0.515000f,0.530000f,0.545000f,0.560000f,0.575000f,0.590000f,0.605000f,0.620000f,0.635000f,0.650000f,0.665000f,0.680000f,0.695000f,0.710000f,0.725000f,0.740000f,0.755000f,0.770000f,0.785000f,0.800000f,0.815000f,0.830000f,0.845000f,0.860000f,0.875000f,0.890000f,0.905000f,0.920000f,0.935000f,0.950000f,0.965000f,0.980000f,0.995000f,1.010000f,1.025000f,1.040000f,1.055000f,1.070000f,1.085000f,1.100000f,1.115000f,1.130000f,1.145000f,1.160000f,1.175000f,1.190000f,1.205000f,1.220000f,1.235000f,1.250000f,1.265000f,1.280000f,1.295000f,1.310000f,1.325000f,1.340000f,1.355000f,1.370000f,1.385000f,1.400000f,1.415000f,1.430000f,1.445000f,1.460000f,1.475000f,1.490000f,1.505000f,1.520000f,1.535000f,1.550000f,1.565000f,1.580000f,1.595000f,1.610000f,1.625000f,1.640000f,1.655000f,1.670000f,1.685000f,1.700000f,1.715000f,1.730000f,1.745000f,1.760000f,1.775000f,1.790000f,1.805000f,1.820000f,1.835000f,1.850000f,1.865000f,1.880000f,1.895000f,1.910000f,1.925000f,1.940000f,1.955000f,1.970000f,1.985000f,2.000000f};

// [0] Data
			testCases.Add(new TestCase("ICPT",DateTime.Parse("12/31/2019"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("AMD",DateTime.Parse("09/28/2018"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("AVAV",DateTime.Parse("09/28/2018"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("ULH",DateTime.Parse("08/31/2018"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("ADT",DateTime.Parse("11/29/2019"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("VC",DateTime.Parse("11/29/2019"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("VIVO",DateTime.Parse("07/31/2020"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("AKS",DateTime.Parse("12/30/2016"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("PRO",DateTime.Parse("07/31/2019"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("RCKT",DateTime.Parse("01/31/2020"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("ENPH",DateTime.Parse("01/29/2021"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("ACLS",DateTime.Parse("11/30/2017"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("KURA",DateTime.Parse("11/30/2020"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("PTLA",DateTime.Parse("03/29/2019"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("SSRI",DateTime.Parse("07/29/2016"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("CORE",DateTime.Parse("09/28/2018"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("OKTA",DateTime.Parse("06/28/2019"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("CTMX",DateTime.Parse("03/29/2018"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("TDOC",DateTime.Parse("08/31/2018"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("WRD",DateTime.Parse("05/31/2018"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("FTCH",DateTime.Parse("12/31/2020"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("COKE",DateTime.Parse("10/30/2015"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));

			dataProcessor.SetOutputFolderPath(@"C:\boneyard\DeepLearning\ModelInputData\0");
			dataProcessor.ProcessData(testCases);
			testCases.Clear();

// [1] Data
			testCases.Add(new TestCase("AG",DateTime.Parse("03/31/2016"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("NKTR",DateTime.Parse("11/30/2017"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("ABX",DateTime.Parse("03/31/2016"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("PTON",DateTime.Parse("09/30/2020"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("CLVS",DateTime.Parse("03/31/2017"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("TREE",DateTime.Parse("06/30/2017"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("BTG",DateTime.Parse("04/29/2016"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("SIG",DateTime.Parse("03/31/2021"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("COOP",DateTime.Parse("09/30/2020"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("THC",DateTime.Parse("03/29/2018"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("ARWR",DateTime.Parse("07/31/2019"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("BAND",DateTime.Parse("06/30/2020"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("TSLA",DateTime.Parse("07/31/2020"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("VEDL",DateTime.Parse("08/31/2016"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("GTHX",DateTime.Parse("04/30/2018"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("PDD",DateTime.Parse("05/29/2020"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("KRO",DateTime.Parse("01/31/2017"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("CPRI",DateTime.Parse("01/29/2021"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("SQ",DateTime.Parse("08/31/2020"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("EHTH",DateTime.Parse("02/28/2019"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("NVCR",DateTime.Parse("10/30/2020"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("FRPT",DateTime.Parse("07/31/2018"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("TLRD",DateTime.Parse("01/31/2018"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("BVN",DateTime.Parse("05/31/2016"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));
			testCases.Add(new TestCase("DNR",DateTime.Parse("06/29/2018"),dayCount,TestCase.CaseType.Training,TestCase.GenerateType.BollingerBand));

			dataProcessor.SetOutputFolderPath(@"C:\boneyard\DeepLearning\ModelInputData\1");
		  dataProcessor.ProcessData(testCases);
		}

		public static void GenerateGeneralizedData()
		{
		   TestCases testCases=new TestCases();	
			 DataProcessor dataProcessor=new DataProcessor();
			 dataProcessor.Width=128;
			 dataProcessor.Height=128;
			 dataProcessor.PenWidth=1;
			 int dayCount=270;

			 string[,] s=new string[,]{{"CWH","01/31/2020"},{"DISCA","02/26/2021"},{"ANAB","02/28/2018"},{"SPWR","07/31/2017"},{"DNLI","12/31/2020"},{"IDTI","11/30/2015"},{"PRO","07/31/2019"},{"ACLS","11/30/2017"},{"TDOC","08/31/2018"},{"ATHM","08/31/2017"},{"SIG","10/30/2020"},{"DOCU","05/29/2020"},{"MTDR","03/31/2021"},{"NTLA","12/31/2020"},{"SE","06/30/2020"},{"BAND","06/30/2020"},{"PDD","05/29/2020"},{"CRSP","03/29/2018"},{"DAC","04/30/2021"}};
			 for(int index=0;index<s.Length/2;index++)
			 {
			  String symbol=s[index,0];
			  DateTime purchaseDate=DateTime.Parse(s[index,1]);
			  TestCase testCase=new TestCase(symbol,purchaseDate,dayCount,TestCase.CaseType.Test,TestCase.GenerateType.BollingerBand);
			  testCases.Add(testCase);
			 }
			dataProcessor.SetOutputFolderPath(@"C:\boneyard\DeepLearning\IndividualValidationCases");
		  dataProcessor.ProcessData(testCases);
		}
		public static String Predict()
		{
		  return "";
		}

		public static void TestPredictAPI()
		{
      String strPathOutputFile = @"C:\boneyard\DeepLearning\TestPredictAPIOutput\outputcases_europa.csv";
      CNNClient cnnClient = new CNNClient("http://10.0.0.73:5000");

      //   String strPathOutputFile=@"C:\boneyard\DeepLearning\TestPredictAPIOutput\outputcases_ganymede.csv";
      //CNNClient cnnClient=new CNNClient("http://192.168.0.151:5000");

      if (!cnnClient.Ping())
			{
			  Console.WriteLine("Model server is not reachable.");
				return;
			}
		  DataProcessor dataProcessor=new DataProcessor();
			dataProcessor.Width=128;
			dataProcessor.Height=128;
			dataProcessor.PenWidth=1;
		  int dayCount=270;

      if(File.Exists(strPathOutputFile))
      {
        try{File.Delete(strPathOutputFile);}
        catch(Exception exception)
        {
          Console.WriteLine(String.Format("Exception:{0}",exception.ToString()));
          throw;
        }
      }
      StreamWriter streamWriter=new StreamWriter(new FileStream(strPathOutputFile,FileMode.CreateNew));
			string[,] s=new string[,]{{"CWH","01/31/2020"},{"DISCA","02/26/2021"},{"ANAB","02/28/2018"},{"SPWR","07/31/2017"},{"DNLI","12/31/2020"},{"IDTI","11/30/2015"},{"PRO","07/31/2019"},{"ACLS","11/30/2017"},{"TDOC","08/31/2018"},{"ATHM","08/31/2017"},{"SIG","10/30/2020"},{"DOCU","05/29/2020"},{"MTDR","03/31/2021"},{"NTLA","12/31/2020"},{"SE","06/30/2020"},{"BAND","06/30/2020"},{"PDD","05/29/2020"},{"CRSP","03/29/2018"},{"DAC","04/30/2021"}};
      streamWriter.WriteLine("Symbol,Date,Response,Response,Raw Response");
      MDTrace.WriteLine(LogLevel.DEBUG,"Symbol,Date,Response,Response,Raw Response");
			for(int index=0;index<s.Length/2;index++)
			{
        StringBuilder sb=new StringBuilder();
				String symbol=s[index,0];
				DateTime purchaseDate=DateTime.Parse(s[index,1]);
				TestCase testCase=new TestCase(symbol,purchaseDate,dayCount,TestCase.CaseType.Test,TestCase.GenerateType.BollingerBand,TestCase.OutputType.OutputStream);
				dataProcessor.ProcessData(testCase);
//				testCase.Responses.Add(cnnClient.Predict(CNNClient.Model.lenet5,testCase.LastStream));
				testCase.Responses.Add(cnnClient.Predict(CNNClient.Model.resnet50,testCase.LastStream));
        String strPredictionResponse=testCase.LastResponse;

        String strPredictionResult=strPredictionResponse.Substring(strPredictionResponse.IndexOf("-->")+3);
        int result=int.Parse(Utility.BetweenString(strPredictionResult,"[[","]"));

        String strPredictionValue=strPredictionResponse.Substring(0,strPredictionResponse.IndexOf("-->"));
        double value=double.Parse(Utility.BetweenString(strPredictionValue,"[[","]"));
        sb.Append(symbol);
        sb.Append(",");
        sb.Append(Utility.AddQuotes(Utility.DateTimeToStringMMSDDSYYYY(purchaseDate)));
        sb.Append(",");
        sb.Append(Utility.AddQuotes(Utility.FormatNumber(value,8,false))).Append(",").Append(Utility.AddQuotes(result.ToString()));
        sb.Append(",").Append(Utility.AddQuotes(strPredictionResponse));
				MDTrace.WriteLine(LogLevel.DEBUG,sb.ToString());
        streamWriter.WriteLine(sb.ToString());
			}
      streamWriter.Flush();
      streamWriter.Close();
      streamWriter.Dispose();

		}
    public static void divide(double divisions,double seedMin,double seedMax)
    {
      double skip=(seedMax-seedMin)/divisions;
      List<double> array=new List<double>();
      for(double seed=seedMax;seed>=seedMin;seed-=skip)
      {
        if(array.Count==divisions)break;
        array.Add(seed);
      }

      for(int index=array.Count-1;index>=0;index--)
      {
        Console.Write(String.Format("{0}f,",Utility.FormatNumber(array[index],6)));
      }
      Console.WriteLine("");
    }
	}
		//TestCases minerviniCases=new TestCases();
		//minerviniCases.Add(new TestCase("SNAP",DateTime.Parse("07-08-2020"),DateTime.Parse("09-13-2020")));
		//minerviniCases.Add(new TestCase("TAL",DateTime.Parse("03-05-2020"),DateTime.Parse("06-01-2020")));
		//minerviniCases.Add(new TestCase("TSM",DateTime.Parse("02-25-2020"),DateTime.Parse("07-01-2020")));
		//minerviniCases.Add(new TestCase("TGT",DateTime.Parse("05-15-2020"),DateTime.Parse("08-03-2020")));
		//dataProcessor.ProcessData(minerviniCases);

}
