private void ValidateSaveApiClient(ApiClientModel model)
        {
            var keyExist = _apiClientBusiness.DoesKeyExist(model.ApiClientId, model.Key);

            if (keyExist)
            {
                Error = string.Format("Api Client {0} could not be saved because the key '{1}' already exists.", model.Name, model.Key);
                return;
            }

            var nameExist = _apiClientBusiness.DoesNameExist(model.ApiClientId, model.Name);

            if (nameExist)
            {
                Error = string.Format("Api Client {0} could not be saved because the name '{0}' already exists.", model.Name);
            }
            if (model.SecretDisplay != Domain.SecretDisplayConstant.SecretDisplayHashed)
            {
                if (model.SecretDisplay.Trim().Length < 16)
                {
                    Error = string.Format("Api Client {0} could not be saved because the secret must be at least 16 characters.", model.Name);
                    return;
                }
                if (model.SecretDisplay.Trim() == model.Key)
                {
                    Error = string.Format("Api Client {0} could not be saved because the secret must not match the key.", model.Name);
                    return;
                }
                if (model.SecretDisplay.Trim() == model.Name)
                {
                    Error = string.Format("Api Client {0} could not be saved because the secret must not match the name.", model.Name);
                    return;
                }
            }
        }
        public EmailToSend Subscribe(string wamsId, int edOrgId, string vendorName, string claimSetName, int?[] selectedSchoolIds = null)
        {
            var agency = _agencyBusiness.GetCurrentYearImpersonatableAgencyByKey(edOrgId);
            var vendor = _vendorBusiness.GetVendorByName(vendorName);

            var users  = _userBusiness.GetUsers(vendor.VendorId).Where(u => !string.IsNullOrEmpty(u.Email)).ToList();
            int?userId = users.Any() ? users.FirstOrDefault()?.UserId : null;

            var applications = _applicationBusiness.GetApplicationsByVendor(vendor.VendorId);

            if (applications.All(a => a.ClaimSetName != claimSetName))
            {
                throw new Exception(string.Format("User can't subscribe to a vendor '{0}' because no application exists for the vendor '{0}' and claim set '{1}'", vendor.VendorName, claimSetName));
            }
            var claimsetDetail = _claimSetBusiness.GetClaimSetDetails(claimSetName);

            if (claimsetDetail.SchoolLevelClaimset && selectedSchoolIds == null)
            {
                throw new Exception("At least one school must be selected.");
            }


            Application application = applications.FirstOrDefault(a => a.ClaimSetName == claimSetName);

            if (application == null)
            {
                application = _applicationBusiness.GetOrCreateApplication(wamsId, vendor.VendorId,
                                                                          claimSetName, claimsetDetail.ProfileId.GetValueOrDefault(), $"{vendor.VendorName} {claimSetName}");
            }


            var key = $"{vendor.VendorName} - {agency.EducationOrganizationId} - {agency.Name}";

            key = key.Substring(0, Math.Min(key.Length, 50));
            var secret = Guid.NewGuid().ToString().Replace("-", "");

            if (_apiClientBusiness.DoesKeyExist(0, key))
            {
                key = key.Substring(0, Math.Min(key.Length, 50) - (claimSetName.Length + 4)) + " - " + claimSetName + " ";
                if (_apiClientBusiness.DoesKeyExist(0, key))
                {
                    int i = 0;
                    while (_apiClientBusiness.DoesKeyExist(0, key) && i < 10)
                    {
                        key = key.Substring(0, Math.Min(key.Length, 47));
                        key = key + " x" + i.ToString();
                        i++;
                    }

                    if (i == 10)
                    {
                        throw new Exception("Please contact DPI to subscribe to this vendor again.");
                    }
                }
            }

            var apiClient = new ApiClient
            {
                Key         = key,
                Secret      = secret,
                Name        = key,
                IsApproved  = true,
                UseSandbox  = false,
                SandboxType = 1,
                ApplicationApplicationId = application?.ApplicationId,
                UserUserId = userId
            };

            if (claimsetDetail.SchoolLevelClaimset && selectedSchoolIds != null && selectedSchoolIds.Length > 0)
            {
                var schoolIds = "";
                foreach (var schoolId in selectedSchoolIds)
                {
                    if (!schoolId.HasValue)
                    {
                        continue;
                    }
                    schoolIds = schoolIds + schoolId.ToString().PadLeft(6, '0') + ",";
                    var schoolApplicationEdOrg =
                        _applicationEducationOrganizationBusiness.GetOrCreateApplicationEducationOrganization(wamsId, schoolId.Value, vendor.VendorId, application?.ApplicationId ?? 0);
                    apiClient.ApplicationEducationOrganizations.Add(schoolApplicationEdOrg);
                }
                key           = $"{vendor.VendorName} - {schoolIds}  {agency.Name}";
                key           = key.Substring(0, Math.Min(key.Length, 50));
                apiClient.Key = key;
            }
            else
            {
                var applicationEdOrg = _applicationEducationOrganizationBusiness.GetOrCreateApplicationEducationOrganization(wamsId, edOrgId, vendor.VendorId, application?.ApplicationId ?? 0);
                apiClient.ApplicationEducationOrganizations.Add(applicationEdOrg);
            }

            _apiClientBusiness.Create(wamsId, apiClient);

            _adminDbContext.Subscriptions.Add(new Subscription
            {
                EducationOrganizationId = edOrgId,
                SubscriptionActionId    = (int)SubscriptionActionEnum.Subscribe,
                VendorId    = vendor.VendorId,
                WamsId      = wamsId,
                CreatedDate = DateTime.Now
            });
            _adminDbContext.SaveChanges(wamsId);

            var edCredUrl = ConfigurationManager.AppSettings["EdCredUrl"];

            var bodySb = new StringBuilder();

            bodySb.Append("<div>" + agency.Name + " has subscribed to your student information system (SIS).  This subscription provides the security credentials needed for WISEdata Ed-Fi integration between their SIS implementation and the Wisconsin DPI Ed-Fi API resources.</div>");
            bodySb.Append("<br/>");
            bodySb.Append("<div>" + "Login to the <a href='" + edCredUrl +
                          "'>Ed-Fi Credential application</a> to view your credentials. Please <a href='http://dpi.wi.gov/wisedata/vendors/contact-us'>contact us</a> with any issues or questions.</div>");
            bodySb.Append("<br/>");
            bodySb.Append("<div>Thanks!</div>");
            bodySb.Append("<br/>");
            bodySb.Append("<div>System Administrator</div>");
            bodySb.Append("<div>Division For Libraries and Technology</div>");
            bodySb.Append("<div>Wisconsin Department of Public Instruction</div>");

            EmailToSend email = new EmailToSend
            {
                From            = "*****@*****.**",
                To              = users.Select(u => u.Email),
                Subject         = "WISEdata Ed-Fi Integration - Agency Credentials Issued",
                Body            = bodySb.ToString(),
                ApplicationName = "EdFi.Credential"
            };

            return(email);
        }