Source

TrafficLight / src / Core / Presenters / EditProjectPresenter.cs

using System;
using System.Collections.Generic;
using RossCode.TrafficLight.Core.Domain;
using RossCode.TrafficLight.Core.Domain.Repositories;
using RossCode.TrafficLight.Core.Factories;
using RossCode.TrafficLight.Core.Presenters.Views;
using System.Linq;

namespace RossCode.TrafficLight.Core.Presenters
{
    public class EditProjectPresenter : PresenterBase<IEditProjectView>
    {
        private class ValidationResult
        {
            private readonly IList<string> errorMessages = new List<string>();

            public bool IsValid
            {
                get { return !ErrorMessages.Any(); }
            }

            public IEnumerable<string> ErrorMessages
            {
                get { return errorMessages; }
            }

            public void AddError(string errorMessage)
            {
                errorMessages.Add(errorMessage);
            }
        }

        private readonly IProjectRepository projectRepository;
        private readonly IProjectResolverFactory projectResolverFactory;
        private Project currentProject;

        public EditProjectPresenter(IEditProjectView view, IProjectRepository projectRepository, IProjectResolverFactory projectResolverFactory) : base(view)
        {
            this.projectRepository = projectRepository;
            this.projectResolverFactory = projectResolverFactory;
            View.SaveProject += SaveProject;
            view.TestProject += TestProject;
        }

        private void TestProject()
        {
            var result = ValidateView();
            if (!result.IsValid)
            {
                View.Alert(string.Join("\n", result.ErrorMessages));
                return;
            }

            var testProject = new Project();
            SetValuesFor(testProject);

            var status = projectResolverFactory.GetProjectResolverFor(testProject).CheckStatus(testProject);
            View.Alert(status == BuildStatus.Unknown ? "Failure" : "Success");
        }

        private void SaveProject()
        {
            var result = ValidateView();
            if (!result.IsValid)
            {
                View.Alert(string.Join("\n", result.ErrorMessages));
                return;
            }

            if (currentProject == null) 
            {
                currentProject = new Project();
            }

            SetValuesFor(currentProject);
            projectRepository.Save(currentProject);
            View.Close();
        }

        private void SetValuesFor(Project project)
        {
            project.Name = View.ProjectName;
            project.Url = View.ProjectUrl;
            project.Username = View.Username;
            project.Password = View.Password;
            project.ServerType = View.ServerType;
        }

        private ValidationResult ValidateView()
        {
            var result = new ValidationResult();

            if (string.IsNullOrWhiteSpace(View.ProjectUrl)) result.AddError("Project URL is required.");
            Uri validatedUri;
            if (!Uri.TryCreate(View.ProjectUrl, UriKind.Absolute, out validatedUri)) result.AddError("Project URL is not a valid URL");
            if (View.ServerType == ServerTypes.Unknown) result.AddError("Server type is required.");
            if (!View.MonitorAllProjects && string.IsNullOrWhiteSpace(View.ProjectName)) result.AddError("Name is required.");

            return result;
        }

        public void SetProject(Project projectToEdit)
        {
            currentProject = projectToEdit;
            View.SetupForProject(!currentProject.Id.HasValue || currentProject.Id.Value <= 0);
            View.ProjectName = currentProject.Name;
            View.MonitorAllProjects = string.IsNullOrWhiteSpace(currentProject.Name);
            View.ProjectUrl = currentProject.Url;
            View.Username = currentProject.Username;
            View.Password = currentProject.Password;
            View.ServerType = currentProject.ServerType;
        }
    }
}