/// Copyright 2016 Kopano b.v.
///
/// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License, version 3,
/// as published by the Free Software Foundation.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
/// GNU Affero General Public License for more details.
///
/// You should have received a copy of the GNU Affero General Public License
/// along with this program.If not, see.
///
/// Consult LICENSE file for details
using Acacia.Stubs;
using Acacia.Stubs.OutlookWrappers;
using Acacia.Utils;
using Acacia.ZPush.Connect;
using Microsoft.Win32;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Security;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Acacia.ZPush
{
[TypeConverter(typeof(ExpandableObjectConverter))]
public class ZPushAccount : LogContext
{
#region Miscellaneous
private readonly IAccount _account;
internal ZPushAccount(IAccount account)
{
this._account = account;
}
[Browsable(false)]
public IAccount Account { get { return _account; } }
public string DisplayName { get { return _account.DisplayName; } }
public string DeviceId { get { return _account.DeviceId; } }
[Browsable(false)]
public string LogContextId
{
get
{
return "ZPushAccount(" + _account.SmtpAddress + ")";
}
}
public override string ToString()
{
return _account.SmtpAddress;
}
#endregion
#region Identification and capabilities
public enum ConfirmationType
{
Unknown,
IsZPush,
IsNotZPush
}
public ConfirmationType Confirmed
{
get;
private set;
}
public delegate void ConfirmationHandler(ZPushAccount account);
private ConfirmationHandler _confirmedChanged;
public event ConfirmationHandler ConfirmedChanged
{
add
{
_confirmedChanged += value;
if (Confirmed != ConfirmationType.Unknown)
value(this);
}
remove
{
_confirmedChanged -= value;
}
}
public ZPushCapabilities Capabilities
{
get;
private set;
}
public string GABFolder
{
get;
private set;
}
public string GABFolderLinked
{
get;
private set;
}
public string ZPushVersion
{
get;
private set;
}
public string ServerSignaturesHash
{
get;
private set;
}
public void LinkedGABFolder(IFolder folder)
{
GABFolderLinked = folder.EntryID;
}
internal void OnConfirmationResponse(ZPushConnection.Response response)
{
Capabilities = response.Capabilities;
// TODO: move these properties to the features? Though it's nice to have them here for the debug dialog
GABFolder = response.GABName;
ZPushVersion = response.ZPushVersion;
ServerSignaturesHash = response.SignaturesHash;
Confirmed = Capabilities == null ? ConfirmationType.IsNotZPush : ConfirmationType.IsZPush;
Logger.Instance.Info(this, "ZPush confirmation: {0} -> {1}, {2}", Confirmed, Capabilities, GABFolder);
_confirmedChanged?.Invoke(this);
}
#endregion
#region Connections
///
/// Creates a new connection to the server for this account.
///
/// If specified, a cancellation token for the connection.
/// The connection. The caller must dispose this when no longer needed.
public ZPushConnection Connect(CancellationToken? cancel = null)
{
return new ZPushConnection(this, null);
}
#endregion
#region Feature-specific data
private readonly ConcurrentDictionary _featureData = new ConcurrentDictionary();
private string FeatureKey(Features.Feature feature, string key)
{
return feature.Name + ":" + key;
}
///
/// Retrieves feature-specific data.
///
/// The type of the data.
/// The feature owning the data.
/// A key identifying the data. This is unique per feature.
/// The data, or null if no data was found.
public DataType GetFeatureData(Features.Feature feature, string key)
{
object val = null;
_featureData.TryGetValue(FeatureKey(feature, key), out val);
return (DataType)val;
}
///
/// Sets feature-specific data on the account. This can be used to cache data for an account
/// that will only be updated periodically.
///
/// The feature owning the data.
/// A key indentifying the data. This is unique per feature.
/// The data. Specify null to remove the entry.
public void SetFeatureData(Features.Feature feature, string key, object data)
{
if (data == null)
{
object dummy;
_featureData.TryRemove(FeatureKey(feature, key), out dummy);
}
else
{
_featureData[FeatureKey(feature, key)] = data;
}
}
#endregion
}
}