//private static async Task<Site> CreateSite(ResourceGroup resourceGroup, Func<string> nameGenerator, string siteKind = null)
        //{
        //    var site = new Site(resourceGroup.SubscriptionId, resourceGroup.ResourceGroupName, nameGenerator(), siteKind);
        //    await resourceGroup.LoadServerFarms(serverFarms: null);
        //    var serverFarm = new ServerFarm(resourceGroup.SubscriptionId, resourceGroup.ResourceGroupName,
        //        Constants.DefaultServerFarmName, resourceGroup.GeoRegion);
        //    if (resourceGroup.ServerFarms.Count() < 1) {
        //        var csmServerFarmResponse =
        //            await
        //                GetClient(resourceGroup.SubscriptionType).HttpInvoke(HttpMethod.Put, ArmUriTemplates.ServerFarmCreate.Bind(serverFarm),
        //                    new
        //                    {
        //                        location = resourceGroup.GeoRegion,
        //                        kind = "app",
        //                        name = serverFarm.ServerFarmName,
        //                        sku= serverFarm.Sku,
        //                        properties = new
        //                        {
        //                            name = serverFarm.ServerFarmName,
        //                            workerSizeId=0,
        //                            numberOfWorkers= 0,
        //                            geoRegion=resourceGroup.GeoRegion,
        //                            kind="app"
        //                        }
        //                    });
        //        await csmServerFarmResponse.EnsureSuccessStatusCodeWithFullError();
        //    }

        //    var csmSiteResponse =
        //        await
        //            GetClient(resourceGroup.SubscriptionType).HttpInvoke(HttpMethod.Put, ArmUriTemplates.SiteCreate.Bind(site),
        //                new
        //                {
        //                    properties =
        //                        new
        //                        {
        //                            serverFarmId = serverFarm.CsmId
        //                        },
        //                    location = resourceGroup.GeoRegion,
        //                    kind = "app",
        //                    name = site.SiteName
        //                });
        //    await csmSiteResponse.EnsureSuccessStatusCodeWithFullError();
        //    var csmSite = await csmSiteResponse.Content.ReadAsAsync<CsmWrapper<CsmSite>>();

        //    return await Load(site, csmSite);
        //}

        private static async Task <Site> CreateLinuxSite(ResourceGroup resourceGroup, Func <string> nameGenerator, string siteKind = null)
        {
            var site = new Site(resourceGroup.SubscriptionId, resourceGroup.ResourceGroupName, nameGenerator(), siteKind);
            var csmTemplateString = string.Empty;
            var template          = TemplatesManager.GetTemplates().FirstOrDefault(t => t.Name == Constants.NodejsWebAppLinuxTemplateName) as LinuxTemplate;

            using (var reader = new StreamReader(template.CsmTemplateFilePath))
            {
                csmTemplateString = await reader.ReadToEndAsync();
            }

            csmTemplateString = csmTemplateString
                                .Replace("{{siteName}}", site.SiteName)
                                .Replace("{{aspName}}", site.SiteName + "-plan")
                                .Replace("{{vmLocation}}", resourceGroup.GeoRegion)
                                .Replace("{{serverFarmType}}", SimpleSettings.ServerFarmTypeContent);
            var inProgressOperation = new InProgressOperation(resourceGroup, DeploymentType.CsmDeploy);
            await inProgressOperation.CreateDeployment(JsonConvert.DeserializeObject <JToken>(csmTemplateString), block : true, subscriptionType : resourceGroup.SubscriptionType);

            // Dont run this yet. Spot serverfarms clock will start
            //await Util.DeployLinuxTemplateToSite(template, site);

            if (!resourceGroup.Tags.ContainsKey(Constants.LinuxAppDeployed))
            {
                resourceGroup.Tags.Add(Constants.LinuxAppDeployed, "1");
                await resourceGroup.Update();
            }
            await Load(site, null);

            return(site);
        }
        private static async Task <Site> CreateVSCodeLinuxSite(ResourceGroup resourceGroup, Func <string> nameGenerator, string siteKind = null)
        {
            var jsonSettings = new JsonSerializerSettings {
                NullValueHandling = NullValueHandling.Ignore
            };
            var site = new Site(resourceGroup.SubscriptionId, resourceGroup.ResourceGroupName, nameGenerator(), siteKind);
            var csmTemplateString = string.Empty;
            var template          = TemplatesManager.GetTemplates().FirstOrDefault(t => t.Name == resourceGroup.TemplateName);

            SimpleTrace.TraceInformation($"Deploying {template.Name} to {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}");

            csmTemplateString = await GetConfig(template.ARMTemplateLink);

            csmTemplateString = csmTemplateString
                                .Replace("{{appServiceName}}", site.SiteName)
                                .Replace("{{msdeployPackageUrl}}", template.MSDeployPackageUrl)
                                .Replace("{{serverFarmType}}", SimpleSettings.ServerFarmTypeContent)
                                .Replace("{{tryAppserviceUrl}}", SimpleSettings.TryAppServiceSite);

            var inProgressOperation = new InProgressOperation(resourceGroup, DeploymentType.CsmDeploy);
            var token = await inProgressOperation.CreateDeployment(JsonConvert.DeserializeObject <JToken>(csmTemplateString), block : true, subscriptionType : resourceGroup.SubscriptionType);

            SimpleTrace.TraceInformation($"ARM Deployment result: {JsonConvert.SerializeObject(token)} to {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}");
            var csmSiteResponse =
                await
                GetClient(resourceGroup.SubscriptionType).HttpInvoke(HttpMethod.Get, ArmUriTemplates.SiteCreate.Bind(site));

            await csmSiteResponse.EnsureSuccessStatusCodeWithFullError();

            var csmSite = await csmSiteResponse.Content.ReadAsAsync <CsmWrapper <CsmSite> >();

            await Load(site, csmSite);

            SimpleTrace.TraceInformation($"Site Loaded from ARM : {JsonConvert.SerializeObject(site)} to {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}");

            var siteguid = await Util.UpdatePostDeployAppSettings(site);

            SimpleTrace.TraceInformation($"Site AppSettings Updated:  for {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}");

            if (resourceGroup.AppService == AppService.VSCodeLinux)
            {
                await Task.Delay(30 * 1000);

                try
                {
                    var lsm = new LinuxSiteManager.Client.LinuxSiteManager(retryCount: 30);
                    await lsm.CheckSiteDeploymentStatusAsync(site.HttpUrl);
                }
                catch (Exception ex)
                {
                    SimpleTrace.TraceError($"Unable to ping deployed site {site.HostName}. Continuing regardless {ex.Message}->{ex.StackTrace} ");
                }
            }
            if (!resourceGroup.Tags.ContainsKey(Constants.TemplateName))
            {
                resourceGroup.Tags.Add(Constants.TemplateName, resourceGroup.TemplateName);
            }
            if (resourceGroup.SubscriptionType == SubscriptionType.AppService)
            {
                if (template != null && template.FileName != null)
                {
                    var  credentials       = new NetworkCredential(site.PublishingUserName, site.PublishingPassword);
                    var  vfsSCMManager     = new RemoteVfsManager(site.ScmUrl + "vfs/", credentials, retryCount: 3);
                    Task scmRedirectUpload = vfsSCMManager.Put("site/applicationHost.xdt", Path.Combine(HostingEnvironment.MapPath(@"~/App_Data"), "applicationHost.xdt"));
                    var  vfsManager        = new RemoteVfsManager(site.ScmUrl + "vfs/", credentials, retryCount: 3);

                    await Task.WhenAll(scmRedirectUpload);
                }
            }
            if (template.Name.Equals("WordPress", StringComparison.OrdinalIgnoreCase))
            {
                await site.UpdateConfig(new { properties = new { scmType = "LocalGit", httpLoggingEnabled = true, localMySqlEnabled = true } });
            }
            resourceGroup.Tags[Constants.TemplateName] = template.Name;
            site.SubscriptionId = resourceGroup.SubscriptionId;
            //site.AppSettings = new Dictionary<string, string>();
            resourceGroup.Tags.Add(Constants.SiteGuid, siteguid);

            await Task.WhenAll(resourceGroup.Update());

            SimpleTrace.TraceInformation($"ResourceGroup Templates Tag Updated: with SiteGuid: {siteguid} for {site.SiteName} ->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}");
            return(site);
        }
        private static async Task <Site> CreateVSCodeLinuxSite(ResourceGroup resourceGroup, Func <string> nameGenerator, string siteKind = null)
        {
            var jsonSettings = new JsonSerializerSettings {
                NullValueHandling = NullValueHandling.Ignore
            };
            var site = new Site(resourceGroup.SubscriptionId, resourceGroup.ResourceGroupName, nameGenerator(), siteKind);
            var csmTemplateString = string.Empty;
            var template          = TemplatesManager.GetTemplates().FirstOrDefault(t => t.Name == resourceGroup.TemplateName) as VSCodeLinuxTemplate;

            SimpleTrace.TraceInformation($"Deploying {template.Name} to {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}");

            using (var reader = new StreamReader(template.CsmTemplateFilePath))
            {
                csmTemplateString = await reader.ReadToEndAsync();
            }

            csmTemplateString = csmTemplateString
                                .Replace("{{siteName}}", site.SiteName)
                                .Replace("{{aspName}}", site.SiteName + "-plan")
                                .Replace("{{vmLocation}}", resourceGroup.GeoRegion);
            var inProgressOperation = new InProgressOperation(resourceGroup, DeploymentType.CsmDeploy);
            var token = await inProgressOperation.CreateDeployment(JsonConvert.DeserializeObject <JToken>(csmTemplateString), block : true, subscriptionType : resourceGroup.SubscriptionType);

            SimpleTrace.TraceInformation($"ARM Deployment result: {JsonConvert.SerializeObject(token)} to {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}");
            await Load(site, null);

            SimpleTrace.TraceInformation($"Site Loaded from ARM : {JsonConvert.SerializeObject(site)} to {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}");

            await Util.UpdateVSCodeLinuxAppSettings(site);

            SimpleTrace.TraceInformation($"Site AppSettings Updated:  for {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}");

            //await site.StopSite();
            await Util.DeployVSCodeLinuxTemplateToSite(template, site, false);

            //await site.StartSite();

            var  lsm       = new LinuxSiteManager.Client.LinuxSiteManager(retryCount: 6);
            Task checkSite = lsm.CheckSiteDeploymentStatusAsync(site.HttpUrl);

            try
            {
                await checkSite;
            }
            catch (Exception ex)
            {
                //TODO: Alert on this specifically
                var message = "New Site didnt come up after zip deploy: " + ex.Message + ex.StackTrace;
                SimpleTrace.TraceError(message);
                throw new ZipDeploymentFailedException(message);
            }

            SimpleTrace.TraceInformation($"Site Code Zip PUT and restart complete: {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}");
            if (!resourceGroup.Tags.ContainsKey(Constants.TemplateName))
            {
                resourceGroup.Tags.Add(Constants.TemplateName, resourceGroup.TemplateName);
                await resourceGroup.Update();

                SimpleTrace.TraceInformation($"ResourceGroup Templates Tag Updated: for {site.SiteName}->{resourceGroup.ResourceGroupName}->{resourceGroup.SubscriptionId}");
            }
            return(site);
        }