using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using Tango.Core.Helpers;
using Tango.BL.Entities;
using Tango.Logging;
using Tango.MachineStudio.Common.Update;
using Tango.BL;
using Tango.BL.Enumerations;
namespace Tango.MachineStudio.UpdateService
{
public class MachineStudioUpdateService : IMachineStudioUpdateService
{
private LogManager LogManager = LogManager.Default;
private class PendingUpload
{
public String Token { get; set; }
public String Version { get; set; }
public String UserGuid { get; set; }
public String Comments { get; set; }
public bool ForcedUpdate { get; set; }
public String FilePath { get; set; }
public bool IsStable { get; set; }
}
private static List<PendingUpload> _pendingUploads;
static MachineStudioUpdateService()
{
_pendingUploads = new List<PendingUpload>();
}
public CheckForUpdatesResponse CheckForUpdates(CheckForUpdatesRequest request)
{
LogManager.Log("Request received...");
try
{
CheckForUpdatesResponse response = new CheckForUpdatesResponse();
using (ObservablesContext db = ObservablesContext.CreateDefault(GetServerAddress()))
{
db.Configuration.LazyLoadingEnabled = false;
//Load relation first...
db.Roles.ToList();
db.Permissions.ToList();
db.UsersRoles.ToList();
db.RolesPermissions.ToList();
var user = db.Users.SingleOrDefault(x => x.Email.ToLower() == request.Email.ToLower() && x.Password == request.Password);
if (user != null && user.HasPermission(Permissions.RunMachineStudio) || (request.Email == "ForceUpdate"))
{
var versions = db.MachineStudioVersions.ToList();
MachineStudioVersion latestVersion = null;
if (request.AcceptBetaRelease)
{
latestVersion = versions.OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault();
}
else
{
latestVersion = versions.Where(x => x.Stable).OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault();
}
Version currentVersion = Version.Parse(request.Version);
bool isForcedUpdate = versions.Exists(x => x.ForceUpdate && Version.Parse(x.Version) > currentVersion);
String comments = String.Join(Environment.NewLine, versions.OrderBy(x => Version.Parse(x.Version)).Where(x => Version.Parse(x.Version) > currentVersion).Select(x => x.Comments));
if (latestVersion != null && Version.Parse(latestVersion.Version) > currentVersion)
{
response.IsUpdateAvailable = true;
response.FtpHost = ConfigurationManager.AppSettings["FtpHost"].ToString();
response.UserName = ConfigurationManager.AppSettings["UserName"].ToString();
response.Password = ConfigurationManager.AppSettings["Password"].ToString();
response.FilePath = latestVersion.FtpFilePath;
response.Version = latestVersion.Version;
response.Comments = latestVersion.Comments;
response.ForcedUpdate = isForcedUpdate;
response.IsStable = latestVersion.Stable;
}
}
else
{
throw new FaultException("Invalid user credentials.");
}
}
return response;
}
catch (Exception ex)
{
LogManager.Log(ex);
throw new FaultException(ex.ToString());
}
}
public UploadVersionResponse UploadVersion(UploadVersionRequest request)
{
try
{
UploadVersionResponse response = new UploadVersionResponse();
using (ObservablesContext db = ObservablesContext.CreateDefault(GetServerAddress()))
{
db.Configuration.LazyLoadingEnabled = false;
//Load relation first...
db.Roles.ToList();
db.Permissions.ToList();
db.UsersRoles.ToList();
db.RolesPermissions.ToList();
var user = db.Users.SingleOrDefault(x => x.Email.ToLower() == request.Email.ToLower() && x.Password == request.Password);
if (user != null && user.HasPermission(Permissions.PublishMachineStudioVersion))
{
var latestVersion = db.MachineStudioVersions.ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault();
Version currentVersion = Version.Parse(request.Version);
String newVersionFileName = Path.GetRandomFileName() + ".zip";
String newVersionFilePath = "/machine studio versions/" + newVersionFileName;
if (currentVersion > Version.Parse(latestVersion.Version))
{
response.FtpHost = ConfigurationManager.AppSettings["FtpHost"].ToString();
response.UserName = ConfigurationManager.AppSettings["UserName"].ToString();
response.Password = ConfigurationManager.AppSettings["Password"].ToString();
response.FilePath = newVersionFilePath;
response.FileName = newVersionFileName;
response.Token = Guid.NewGuid().ToString();
_pendingUploads.Add(new PendingUpload()
{
UserGuid = user.Guid,
Comments = request.Comments,
ForcedUpdate = request.ForcedUpdate,
Token = response.Token,
Version = request.Version,
FilePath = response.FilePath,
IsStable = request.IsStable,
});
}
else
{
throw new FaultException("New version must be greater than latest version.");
}
}
else
{
throw new FaultException("Invalid user credentials.");
}
}
return response;
}
catch (Exception ex)
{
LogManager.Log(ex);
throw new FaultException(ex.ToString());
}
}
public void NotifyUploadCompleted(UploadCompletedRequest request)
{
try
{
PendingUpload upload = _pendingUploads.FirstOrDefault(x => x.Token == request.Token);
if (upload != null)
{
_pendingUploads.RemoveAll(x => x.Token == upload.Token);
using (ObservablesContext db = ObservablesContext.CreateDefault(GetServerAddress()))
{
db.Configuration.LazyLoadingEnabled = false;
db.MachineStudioVersions.Add(new MachineStudioVersion()
{
Comments = upload.Comments,
FtpFilePath = upload.FilePath,
UserGuid = upload.UserGuid,
Version = upload.Version,
ForceUpdate = upload.ForcedUpdate,
Stable = upload.IsStable,
});
db.SaveChanges();
}
}
else
{
throw new FaultException("Invalid Token.");
}
}
catch (Exception ex)
{
LogManager.Log(ex);
throw new FaultException(ex.ToString());
}
}
public string GetLatestVersion()
{
try
{
using (ObservablesContext db = ObservablesContext.CreateDefault(GetServerAddress()))
{
return db.MachineStudioVersions.ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault().Version;
}
}
catch (Exception ex)
{
throw new FaultException(ex.ToString());
}
}
private String GetServerAddress()
{
return ConfigurationManager.AppSettings["ServerAddress"].ToString();
}
}
}