private static async Task SaveVideoRecord(string storageBasePath, VideoRecord videoRecord)
        {
            List <VideoRecord> allVideos;
            var videoRecordPath = Path.Combine(storageBasePath, "videos.json");

            if (File.Exists(videoRecordPath))
            {
                var jsonText = await File.ReadAllTextAsync(videoRecordPath);

                allVideos = JsonConvert.DeserializeObject <List <VideoRecord> >(jsonText);
            }
            else
            {
                allVideos = new List <VideoRecord>();
            }

            allVideos.Add(videoRecord);
            await File.WriteAllTextAsync(videoRecordPath, JsonConvert.SerializeObject(allVideos));
        }
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            var storageBasePath = Path.Combine(Directory.GetCurrentDirectory(), "storage");

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await using var indexStream = typeof(Startup).Assembly.GetManifestResourceStream("VideoGallery.index.html");
                    var indexContent            = new StreamReader(indexStream).ReadToEnd();

                    context.Response.ContentType = "text/html";
                    await context.Response.WriteAsync(indexContent);
                });

                endpoints.MapGet("/videos", async context =>
                {
                    context.Response.ContentType = "application/json";
                    var videoRecordPath          = Path.Combine(storageBasePath, "videos.json");
                    if (!File.Exists(videoRecordPath))
                    {
                        await context.Response.WriteAsync("[]");
                        return;
                    }

                    var videoRecordContent = await File.ReadAllTextAsync(videoRecordPath);
                    var videos             = JsonConvert.DeserializeObject <List <VideoRecord> >(videoRecordContent);
                    foreach (var videoRecord in videos)
                    {
                        var durationFile = Path.Combine(storageBasePath, "duration", videoRecord.id + ".txt");
                        if (File.Exists(durationFile))
                        {
                            videoRecord.duration = int.Parse(File.ReadAllText(durationFile));
                        }
                    }
                    await context.Response.WriteAsync(JsonConvert.SerializeObject(videos));
                });

                endpoints.MapGet("/gif", async context =>
                {
                    var videoId    = context.Request.Query["video"].Single();
                    var mappedPath = Path.Combine(storageBasePath, "gif", $"{videoId}.gif");

                    if (!File.Exists(mappedPath))
                    {
                        context.Response.StatusCode = (int)HttpStatusCode.NotFound;
                        return;
                    }

                    context.Response.Headers.Add("Cache-Control", "max-age=86400; public");
                    context.Response.ContentType = "image/gif";
                    await context.Response.SendFileAsync(mappedPath);
                });

                endpoints.MapPost("/upload", async context =>
                {
                    var videoId = Guid.NewGuid().ToString("N");
                    await SaveVideoContent(storageBasePath, videoId, context);

                    var videoRecord = new VideoRecord()
                    {
                        id    = videoId,
                        title = "Video " + videoId.Substring(0, 8)
                    };
                    await SaveVideoRecord(storageBasePath, videoRecord);

                    context.Response.StatusCode = (int)HttpStatusCode.Created;
                    await context.Response.WriteAsync(JsonConvert.SerializeObject(videoRecord));
                });
            });
        }