using Google.Protobuf;
using Microsoft.Azure;
using Microsoft.Azure.Management.Sql;
using Microsoft.SqlServer.Management.Smo;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Authentication;
using System.Threading.Tasks;
using System.Web.Hosting;
using System.Web.Http;
using Tango.BL;
using Tango.BL.Builders;
using Tango.BL.Entities;
using Tango.Core.DB;
using Tango.Core.Helpers;
using Tango.Core.IO;
using Tango.Logging;
using Tango.MachineService.Helpers;
using Tango.MachineService.Models;
using Tango.MachineService.SMO;
using Tango.PMR.Stubs;
using Tango.PMR.Synchronization;
using Tango.Synchronization.Local;
using Tango.Synchronization.Remote;
namespace Tango.MachineService.Controllers
{
public class SynchronizationController : ProtoController
{
/////
///// Expects a DB synchronization request from a remote machine and returns the synchronized version of the machine database.
/////
///// The request.
/////
//[HttpPost]
//public SynchronizeDBResponse Synchronize(SynchronizeDBRequest request)
//{
// var tempFolder = TemporaryManager.Default.CreateFolder();
// try
// {
// //File path for the reflected remote data base SQLite.
// String masterSQLiteFile = Path.Combine(tempFolder, "Remote.db");
// //File path for the received machine SQLite db.
// String slaveSQLiteFile = Path.Combine(tempFolder, "Local.db");
// //Save the machine db to file.
// File.WriteAllBytes(slaveSQLiteFile, request.LocalDB.ToByteArray());
// //Copy an SQLite db template.
// File.Copy(HostingEnvironment.MapPath(@"~/App_Data/Tango.db"), masterSQLiteFile);
// //Synchronize the SQL Server db with the new SQLite template. (Overwrite basically)
// RemoteDBSynchronizer.Synchronize(masterSQLiteFile, request.SerialNumber, true);
// //Synchronize the received machine db with the filled template.
// LocalDBSynchronizer.Synchronize(masterSQLiteFile, slaveSQLiteFile);
// //Send the synchronized machine db to the machine to the machine.
// SynchronizeDBResponse response = new SynchronizeDBResponse();
// response.RemoteDB = ByteString.CopyFrom(File.ReadAllBytes(slaveSQLiteFile));
// return response;
// }
// catch (Exception)
// {
// throw;
// }
// finally
// {
// //Remove all temporary files and folder.
// tempFolder.Delete();
// }
//}
[HttpPost]
public MachineSetupResponse MachineSetup(MachineSetupRequest request)
{
MachineSetupResponse response = new MachineSetupResponse();
LogManager.Log("Setup request received: " + request.ToString());
using (ObservablesContext db = ObservablesContextHelper.CreateContext())
{
db.Configuration.LazyLoadingEnabled = false;
String serial_number = request.SerialNumber;
var machine = db.Machines.SingleOrDefault(x => x.SerialNumber == serial_number);
if (machine == null)
{
throw new AuthenticationException("The specified serial number could not be found.");
}
var machine_version = db.MachineVersions.SingleOrDefault(x => x.Guid == machine.MachineVersionGuid);
var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault();
response.Version = latest_machine_version.Version;
var client = StorageHelper.GetStorageBlobClient();
var container = StorageHelper.GetTangoVersionsContainer(client);
var blob = container.GetBlockBlobReference(latest_machine_version.BlobName);
response.BlobAddress = StorageHelper.GenerateBlobReadSignature(blob, TimeSpan.FromMinutes(60));
DbCredentials credentials = new DbCredentials();
using (SmoManager manager = new SmoManager())
{
credentials = manager.CreateRandomLoginAndUser();
Task.Delay(TimeSpan.FromMinutes(10)).ContinueWith((x) =>
{
using (SmoManager m = new SmoManager())
{
m.DeleteLoginAndUser(credentials.UserName);
}
});
}
response.DbAddress = Config.DB_ADDRESS;
response.DbUserName = credentials.UserName;
response.DbPassword = credentials.Password;
}
return response;
}
[HttpPost]
public DownloadUpdateResponse MachineUpdate(DownloadUpdateRequest request)
{
DownloadUpdateResponse response = new DownloadUpdateResponse();
using (ObservablesContext db = ObservablesContextHelper.CreateContext())
{
db.Configuration.LazyLoadingEnabled = false;
String serial_number = request.SerialNumber;
var machine = db.Machines.SingleOrDefault(x => x.SerialNumber == serial_number);
if (machine == null)
{
throw new AuthenticationException("The specified serial number could not be found.");
}
var machine_version = db.MachineVersions.SingleOrDefault(x => x.Guid == machine.MachineVersionGuid);
var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault();
response.Version = latest_machine_version.Version;
var client = StorageHelper.GetStorageBlobClient();
var container = StorageHelper.GetTangoVersionsContainer(client);
var blob = container.GetBlockBlobReference(latest_machine_version.BlobName);
response.BlobAddress = StorageHelper.GenerateBlobReadSignature(blob, TimeSpan.FromMinutes(60));
DbCredentials credentials = new DbCredentials();
using (SmoManager manager = new SmoManager())
{
credentials = manager.CreateRandomLoginAndUser();
Task.Delay(TimeSpan.FromMinutes(10)).ContinueWith((x) =>
{
using (SmoManager m = new SmoManager())
{
m.DeleteLoginAndUser(credentials.UserName);
}
});
}
response.DbAddress = Config.DB_ADDRESS;
response.DbUserName = credentials.UserName;
response.DbPassword = credentials.Password;
}
return response;
}
[HttpPost]
public CheckForUpdateResponse CheckForUpdate(CheckForUpdateRequest request)
{
CheckForUpdateResponse response = new CheckForUpdateResponse();
using (ObservablesContext db = ObservablesContextHelper.CreateContext())
{
db.Configuration.LazyLoadingEnabled = false;
var machine = db.Machines.SingleOrDefault(x => x.SerialNumber == request.SerialNumber);
if (machine == null)
{
throw new AuthenticationException("The specified serial number could not be found.");
}
var machine_version = db.MachineVersions.SingleOrDefault(x => x.Guid == machine.MachineVersionGuid);
var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault();
if (Version.Parse(latest_machine_version.Version) > Version.Parse(request.Version))
{
response.IsUpdateAvailable = true;
}
response.Version = latest_machine_version.Version;
}
return response;
}
[HttpPost]
public UpdateDBResponse UpdateDB(UpdateDBRequest request)
{
UpdateDBResponse response = new UpdateDBResponse();
using (ObservablesContext db = ObservablesContextHelper.CreateContext())
{
db.Configuration.LazyLoadingEnabled = false;
String serial_number = request.SerialNumber;
var machine = db.Machines.SingleOrDefault(x => x.SerialNumber == serial_number);
if (machine == null)
{
throw new AuthenticationException("The specified serial number could not be found.");
}
DbCredentials credentials = new DbCredentials();
using (SmoManager manager = new SmoManager())
{
credentials = manager.CreateRandomLoginAndUser();
Task.Delay(TimeSpan.FromMinutes(10)).ContinueWith((x) =>
{
using (SmoManager m = new SmoManager())
{
m.DeleteLoginAndUser(credentials.UserName);
}
});
}
response.DbAddress = Config.DB_ADDRESS;
response.DbUserName = credentials.UserName;
response.DbPassword = credentials.Password;
}
return response;
}
[HttpPost]
public Machine PersonTest(Person p)
{
using (var db = ObservablesContextHelper.CreateContext())
{
var machine = new MachineBuilder(db)
.Set(x => x.SerialNumber == "1111")
.WithOrganization()
.WithConfiguration().Build();
return machine;
}
}
}
}