using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BO.BO;
using Forks.JsonRpc.Client;
using Newtonsoft.Json;

namespace BO
{
  public abstract  class SyncToServerBase<T> where T:LocalSyncBase
  {

    private static object lockObj=new object();
    private static object lockSucessedObj=new object();

    protected abstract string InsertRpcUrl { get;  }
    protected abstract string UpdateRpcUrl { get;  }
    protected abstract string DeleteRpcUrl { get; }

    /// <summary>
    /// 是否同步完成
    /// </summary>
    /// <returns></returns>
    public bool IsSyncSucessed()
    {
      lock (lockSucessedObj)
      {
        try
        {
          var forList = LocalDmoSession.GetNeedSyncList<T>();
          //所有集合长度为0时
          return forList.WillInsertList.Count == 0 && forList.WillUpdateList.Count == 0 && forList.WillDeleteList.Count == 0;
        }
        catch (Exception e)
        {
          return false;
        }
      }
    }

    public void SyncToServer()
    {
      lock (lockObj)
      {
        try
        {
          var forList = LocalDmoSession.GetNeedSyncList<T>();
          foreach (T record in forList.WillInsertList)
          {
            Insert(record);
          }

          foreach (T record in forList.WillUpdateList)
          {
            Update(record);
          }

          foreach (T record in forList.WillDeleteList)
          {
            Delete(record);
          }
        }
        catch (Exception e)
        {
          
        }
      }
    }

    private long Insert(T record)
    {
      var json = record.GetDtoJson();
      var serviceid = RpcFacade.Call<long>(InsertRpcUrl, json);
      LocalDmoSession.UpdateAfterInsertSynced<T>(record.ID, serviceid);
      return serviceid;
    }

    private  void Update(T record)
    {
      var json = record.GetDtoJson();
      RpcFacade.Call<int>(UpdateRpcUrl, json);
      LocalDmoSession.UpdateAfterUpdateSynced<T>(record.ID);
    }
 

    private  void Delete(T record)
    {
      var serviceId = record.Service_ID;
      if (serviceId == null)
      {
        return;
      }
      RpcFacade.Call<int>(DeleteRpcUrl, serviceId.Value);
      LocalDmoSession.UpdateAfterDeleteSynced<T>(record.ID);
    }
  }
}
