1+ using Microsoft . AspNetCore . Hosting ;
2+ using Microsoft . Extensions . Hosting ;
3+ using Microsoft . Extensions . Logging ;
4+ using System ;
5+ using System . IO ;
6+ using System . Linq ;
7+ using System . Text . Json ;
8+ using System . Text . Json . Serialization ;
9+ using System . Threading ;
10+ using System . Threading . Tasks ;
11+ using File = System . IO . File ;
12+
13+ namespace KeeperData . Infrastructure . Services ;
14+
15+ /// <summary>
16+ /// A startup service that generates a baseline JSON file from a CSV,
17+ /// but only if the JSON file does not already exist.
18+ /// </summary>
19+ public class JsonGenerationService : IHostedService
20+ {
21+ private readonly IWebHostEnvironment _env ;
22+ private readonly ILogger < JsonGenerationService > _logger ;
23+
24+ // Just the properties we need for now
25+ private record CountryJson (
26+ [ property: JsonPropertyName ( "id" ) ] string Id ,
27+ [ property: JsonPropertyName ( "code" ) ] string Code ,
28+ [ property: JsonPropertyName ( "name" ) ] string Name
29+ ) ;
30+
31+ public JsonGenerationService ( IWebHostEnvironment env , ILogger < JsonGenerationService > logger )
32+ {
33+ _env = env ;
34+ _logger = logger ;
35+ }
36+
37+ public Task StartAsync ( CancellationToken cancellationToken )
38+ {
39+ _logger . LogInformation ( "JSON Generation Service is running." ) ;
40+
41+ var sourceCsvPath = Path . Combine ( _env . ContentRootPath , "Data" , "Source" , "countries.csv" ) ;
42+ var targetJsonPath = Path . Combine ( _env . ContentRootPath , "Data" , "Seed" , "countries.json" ) ;
43+
44+ if ( File . Exists ( targetJsonPath ) )
45+ {
46+ _logger . LogInformation ( "'{FileName}' already exists. Skipping generation." , Path . GetFileName ( targetJsonPath ) ) ;
47+ return Task . CompletedTask ;
48+ }
49+
50+ if ( ! File . Exists ( sourceCsvPath ) )
51+ {
52+ _logger . LogWarning ( "Source file '{FileName}' not found. Cannot generate target JSON." , Path . GetFileName ( sourceCsvPath ) ) ;
53+ return Task . CompletedTask ;
54+ }
55+
56+ try
57+ {
58+ _logger . LogInformation ( "'{TargetFile}' not found. Generating from '{SourceFile}'..." , Path . GetFileName ( targetJsonPath ) , Path . GetFileName ( sourceCsvPath ) ) ;
59+
60+ var lines = File . ReadAllLines ( sourceCsvPath ) ;
61+ var countries = lines
62+ . Skip ( 1 ) // Skip header
63+ . Where ( line => ! string . IsNullOrWhiteSpace ( line ) )
64+ . Select ( line =>
65+ {
66+ var parts = line . Split ( ',' ) ;
67+ return new CountryJson (
68+ Guid . NewGuid ( ) . ToString ( ) ,
69+ parts [ 0 ] . Trim ( ) ,
70+ parts [ 1 ] . Trim ( )
71+ ) ;
72+ } )
73+ . ToList ( ) ;
74+
75+ var options = new JsonSerializerOptions { WriteIndented = true } ;
76+ var jsonString = JsonSerializer . Serialize ( countries , options ) ;
77+
78+ var outputDir = Path . GetDirectoryName ( targetJsonPath ) ;
79+ if ( outputDir != null && ! Directory . Exists ( outputDir ) )
80+ {
81+ Directory . CreateDirectory ( outputDir ) ;
82+ }
83+
84+ File . WriteAllText ( targetJsonPath , jsonString ) ;
85+
86+ _logger . LogInformation ( "Successfully generated '{FileName}' with {Count} records." , Path . GetFileName ( targetJsonPath ) , countries . Count ) ;
87+ }
88+ catch ( Exception ex )
89+ {
90+ _logger . LogError ( ex , "An error occurred while generating JSON from CSV." ) ;
91+ }
92+
93+ return Task . CompletedTask ;
94+ }
95+
96+ public Task StopAsync ( CancellationToken cancellationToken ) => Task . CompletedTask ;
97+ }
0 commit comments