public FamilyRelationshipsWithHotSpots(HotSpot hotSpot1,
                                               RefugeeModel refugee1,
                                               IsFamilyRelationshipData isFamilyRelationshipData1,
                                               RefugeeModel refugee2,
                                               HotSpot hotSpot2,
                                               IsFamilyRelationshipData isFamilyRelationshipData2 = null,
                                               RefugeeModel refugee3 = null,
                                               HotSpot hotSpot3      = null)
        {
            Ensure.That(nameof(hotSpot1)).IsNotNull();

            Ensure.That(nameof(refugee1)).IsNotNull();

            Ensure.That(nameof(isFamilyRelationshipData1)).IsNotNull();

            Ensure.That(nameof(refugee2)).IsNotNull();

            Ensure.That(nameof(hotSpot2)).IsNotNull();

            HotSpot1 = hotSpot1;

            Refugee1 = refugee1;

            IsFamilyRelationshipData1 = isFamilyRelationshipData1;

            Refugee2 = refugee2;

            HotSpot2 = hotSpot2;

            IsFamilyRelationshipData2 = isFamilyRelationshipData2;

            Refugee3 = refugee3;

            HotSpot3 = hotSpot3;
        }
        public RefugeeWithHotSpot(RefugeeModel refugee, HotSpot hotSpot)
        {
            Ensure.That(nameof(refugee)).IsNotNull();

            Ensure.That(nameof(hotSpot)).IsNotNull();

            Refugee = refugee;

            HotSpot = hotSpot;
        }
        public void UnRelate(RefugeeModel refugee)
        {
            Ensure.That(nameof(refugee)).IsNotNull();

            string refugeeLabel = typeof(RefugeeModel).Name;

            string hotSpotLabel = typeof(HotSpot).Name;

            GraphClient.Cypher.Match($"(r:{refugeeLabel})-[o:{LivesInRelationship.TypeKey}]->(h:{hotSpotLabel})")
            .Where((RefugeeModel r) => r.Id == refugee.Id)
            .Delete("o")
            .ExecuteWithoutResults();
        }
        public HotSpot GetByRefugee(RefugeeModel refugee)
        {
            Ensure.That(nameof(refugee)).IsNotNull();

            string refugeeLabel = typeof(RefugeeModel).Name;

            string hotSpotLabel = typeof(HotSpot).Name;

            return(GraphClient.Cypher.Match($"(r:{refugeeLabel})-[:{LivesInRelationship.TypeKey}]->(h:{hotSpotLabel})")
                   .Where((RefugeeModel r) => r.Id == refugee.Id)
                   .Return(h => h.As <HotSpot>())
                   .Results
                   .Single());
        }
        public void RelateRefugees(CreateRefugeesFamilyRelationshipInputDto createRefugeesFamilyRelationshipInputDto)
        {
            if (createRefugeesFamilyRelationshipInputDto == null)
            {
                throw new RestException(HttpStatusCode.BadRequest, Constants.Messages.MissingInputDto, new ArgumentNullException(nameof(createRefugeesFamilyRelationshipInputDto)));
            }

            if (!Enum.IsDefined(typeof(FamilyRelationshipDegree), createRefugeesFamilyRelationshipInputDto.RelationshipDegree))
            {
                throw new RestException(HttpStatusCode.BadRequest, "The provided family relationship degree is not supported.", new ArgumentException("The value of the family relationship degree is not defined in the enumeration."));
            }

            try
            {
                CreateRefugeesFamilyRelationshipInputDtoValidator.ValidateAndThrow(createRefugeesFamilyRelationshipInputDto);
            }
            catch (ValidationException exception)
            {
                throw new RestException(HttpStatusCode.BadRequest, exception.Message, exception);
            }

            using (IUnitOfWork unitOfWork = UnitOfWorkFactory.Create())
            {
                unitOfWork.BeginTransaction();

                RefugeeModel sourceRefugee = unitOfWork.RefugeeRepository.GetById(createRefugeesFamilyRelationshipInputDto.SourceId);

                if (sourceRefugee == null)
                {
                    throw new RestException(HttpStatusCode.NotFound, Constants.Messages.ResourceCannotBeFound, new ArgumentException(Constants.Messages.ResourceCannotBeFound));
                }

                RefugeeModel targetRefugee = unitOfWork.RefugeeRepository.GetById(createRefugeesFamilyRelationshipInputDto.TargetId);

                if (targetRefugee == null)
                {
                    throw new RestException(HttpStatusCode.NotFound, Constants.Messages.ResourceCannotBeFound, new ArgumentException(Constants.Messages.ResourceCannotBeFound));
                }

                FamilyRelationshipDegree relationshipDegree = (FamilyRelationshipDegree)createRefugeesFamilyRelationshipInputDto.RelationshipDegree;

                unitOfWork.RefugeeRelationshipManager.UnRelate(sourceRefugee, targetRefugee);

                unitOfWork.RefugeeRelationshipManager.Relate(sourceRefugee, targetRefugee, new IsFamilyRelationshipData(relationshipDegree));

                unitOfWork.CommitTransaction();
            }
        }
        public void Relate(RefugeeModel refugee, HotSpot hotSpot)
        {
            Ensure.That(nameof(refugee)).IsNotNull();

            Ensure.That(nameof(hotSpot)).IsNotNull();

            string refugeeLabel = typeof(RefugeeModel).Name;

            string hotSpotLabel = typeof(HotSpot).Name;

            GraphClient.Cypher.Match($"(r:{refugeeLabel})", $"(h:{hotSpotLabel})")
            .Where((RefugeeModel r) => r.Id == refugee.Id)
            .AndWhere((HotSpot h) => h.Id == hotSpot.Id)
            .CreateUnique($"(r)-[:{LivesInRelationship.TypeKey}]->(h)")
            .ExecuteWithoutResults();
        }
        public virtual void DeleteRefugee(Guid id)
        {
            if (id == default(Guid))
            {
                throw new RestException(HttpStatusCode.BadRequest, Constants.Messages.InvalidIdentifier, new ArgumentException(Constants.Messages.InvalidIdentifier, nameof(id)));
            }

            using (IUnitOfWork unitOfWork = UnitOfWorkFactory.Create())
            {
                RefugeeModel refugee = unitOfWork.RefugeeRepository.GetById(id);

                if (refugee == null)
                {
                    throw new RestException(HttpStatusCode.NotFound, Constants.Messages.ResourceCannotBeFound, new ArgumentException(Constants.Messages.ResourceCannotBeFound));
                }

                unitOfWork.RefugeeRepository.Delete(refugee);
            }
        }
        public GraphOutputDto GetRelationshipsGraph(Guid id)
        {
            if (id == default(Guid))
            {
                throw new RestException(HttpStatusCode.BadRequest, Constants.Messages.InvalidIdentifier, new ArgumentException(Constants.Messages.InvalidIdentifier, nameof(id)));
            }

            IList <FamilyRelationshipsWithHotSpots> familyRelationshipsWithHotSpots;

            using (IUnitOfWork unitOfWork = UnitOfWorkFactory.Create())
            {
                RefugeeModel refugee = unitOfWork.RefugeeRepository.GetById(id);

                if (refugee == null)
                {
                    throw new RestException(HttpStatusCode.NotFound, Constants.Messages.ResourceCannotBeFound, new ArgumentException(Constants.Messages.ResourceCannotBeFound));
                }

                familyRelationshipsWithHotSpots = unitOfWork.RefugeeRepository.GetFamilyRelationshipsWithHotSpotsByRefugee(refugee);
            }

            IList <NodeOutputDto> nodes = new List <NodeOutputDto>();

            IList <LinkOutputDto> links = new List <LinkOutputDto>();

            #region Mapping Operations

            byte refugeeNodeType = (byte)NodeType.Refugee;

            byte hotSpotNodeType = (byte)NodeType.HotSpot;

            string livesInTypeKey = LivesInRelationship.TypeKey.ToLower();

            foreach (FamilyRelationshipsWithHotSpots familyRelationshipsWithHotSpotsData in familyRelationshipsWithHotSpots)
            {
                #region Nodes

                #region Refugees

                nodes.Add(new NodeOutputDto {
                    Id = familyRelationshipsWithHotSpotsData.Refugee1.Id, Name = familyRelationshipsWithHotSpotsData.Refugee1.Name, Type = refugeeNodeType
                });

                nodes.Add(new NodeOutputDto {
                    Id = familyRelationshipsWithHotSpotsData.Refugee2.Id, Name = familyRelationshipsWithHotSpotsData.Refugee2.Name, Type = refugeeNodeType
                });

                if (familyRelationshipsWithHotSpotsData.Refugee3 != null)
                {
                    nodes.Add(new NodeOutputDto {
                        Id = familyRelationshipsWithHotSpotsData.Refugee3.Id, Name = familyRelationshipsWithHotSpotsData.Refugee3.Name, Type = refugeeNodeType
                    });
                }

                #endregion

                #region HotSpots

                nodes.Add(new NodeOutputDto {
                    Id = familyRelationshipsWithHotSpotsData.HotSpot1.Id, Name = familyRelationshipsWithHotSpotsData.HotSpot1.Name, Type = hotSpotNodeType
                });

                nodes.Add(new NodeOutputDto {
                    Id = familyRelationshipsWithHotSpotsData.HotSpot2.Id, Name = familyRelationshipsWithHotSpotsData.HotSpot2.Name, Type = hotSpotNodeType
                });

                if (familyRelationshipsWithHotSpotsData.HotSpot3 != null)
                {
                    nodes.Add(new NodeOutputDto {
                        Id = familyRelationshipsWithHotSpotsData.HotSpot3.Id, Name = familyRelationshipsWithHotSpotsData.HotSpot3.Name, Type = hotSpotNodeType
                    });
                }

                #endregion

                #endregion

                #region Links

                links.Add(new LinkOutputDto {
                    SourceId = familyRelationshipsWithHotSpotsData.Refugee1.Id, TargetId = familyRelationshipsWithHotSpotsData.HotSpot1.Id, Name = livesInTypeKey
                });

                links.Add(new LinkOutputDto {
                    SourceId = familyRelationshipsWithHotSpotsData.Refugee1.Id, TargetId = familyRelationshipsWithHotSpotsData.Refugee2.Id, Name = familyRelationshipsWithHotSpotsData.IsFamilyRelationshipData1.Degree.ToString().ToLower()
                });

                links.Add(new LinkOutputDto {
                    SourceId = familyRelationshipsWithHotSpotsData.Refugee2.Id, TargetId = familyRelationshipsWithHotSpotsData.HotSpot2.Id, Name = livesInTypeKey
                });

                if (familyRelationshipsWithHotSpotsData.Refugee3 != null)
                {
                    links.Add(new LinkOutputDto {
                        SourceId = familyRelationshipsWithHotSpotsData.Refugee3.Id, TargetId = familyRelationshipsWithHotSpotsData.HotSpot3.Id, Name = livesInTypeKey
                    });

                    links.Add(new LinkOutputDto {
                        SourceId = familyRelationshipsWithHotSpotsData.Refugee2.Id, TargetId = familyRelationshipsWithHotSpotsData.Refugee3.Id, Name = familyRelationshipsWithHotSpotsData.IsFamilyRelationshipData2.Degree.ToString().ToLower()
                    });
                }

                #endregion
            }

            nodes = nodes.DistinctBy(o => o.Id).ToList();

            #endregion

            return(new GraphOutputDto {
                Nodes = nodes, Links = links
            });
        }