public async Task <Response> AddObservation(Observation observation) { try { #region Validation if (string.IsNullOrWhiteSpace(observation.Color) || !new[] { "green", "red" }.Contains(observation.Color)) { throw new ArgumentException("Invalid color. Acceptable values: 'green' or 'red'.", nameof(observation.Color)); } if (observation.Color.Equals("green") && (observation.Numbers.Any(str => str.Length != 7) || observation.Numbers.Any(str => str.Except(new[] { '0', '1' }).Any()))) { throw new ArgumentException(ErrorMessage.InvalidNumberFormat, nameof(observation.Numbers)); } var existingSequence = await UnitOfWork.SequenceRepository.Get(observation.SequenceId); if (existingSequence == null) { throw new KeyNotFoundException(ErrorMessage.SequenceNotFound); } if (!existingSequence.Observations.Any() && observation.Color.Equals("red")) { throw new InvalidOperationException(ErrorMessage.NotEnoughData); } if (existingSequence.Observations.Any(ob => ob.Color.ToLower().Equals("red"))) { throw new InvalidOperationException(ErrorMessage.RedObservationShouldBeLast); } if (observation.Color.Equals("green") && (observation.Numbers.Length != 2 || existingSequence.Observations.Any(ob => ob.Numbers.SequenceEqual(observation.Numbers)))) { throw new ArgumentException(ErrorMessage.NoSolutionsFound); } #endregion if (observation.Color.Equals("red")) { observation.Numbers = new[] { "1110111", "1110111" }; observation.ReadableValue = 0; observation.PossibleReadableValues = new[] { 0 }; } else { observation.ReadableValue = TruthTable.GetHumanReadableValue(observation.Numbers); observation.PossibleReadableValues = TruthTable.GetPossibleNumbers(observation.Numbers).ToArray(); } await UnitOfWork.ObservationRepository.Add(Mapper.Map <Data.Model.Observation>(observation)); foreach (var(number, display) in observation.Numbers.Select((num, i) => (num, i))) { var workingSections = number.Select((c, section) => c == '1' ? section : -1).Where(index => index > -1); await SetWorkingSections(display, workingSections, existingSequence); } await UnitOfWork.Save(); var missing = GetMissingSections(existingSequence.WorkingSections); var possibleStart = GetPossibleStart(existingSequence.Observations); if (possibleStart.Length == 0) { throw new InvalidOperationException(ErrorMessage.NoSolutionsFound); } existingSequence.PossibleStart = possibleStart; existingSequence.Missing = missing; UnitOfWork.SequenceRepository.Update(existingSequence); await UnitOfWork.Save(); return(new Response { Missing = missing, Start = existingSequence.PossibleStart }); } catch (Exception e) { Console.WriteLine(e); throw; } }