const std = @import("std");
const clap = @import("clap");

const server = @import("eink_feed_server");

pub const ConfigFile = struct {
    channels: []server.web.api.models.Channel,
    clients: []server.Config.Client,
};

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{
        .thread_safe = true,
    }){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    {
        const params = comptime clap.parseParamsComptime(
            \\-h, --help        Display this help and exit.
            \\--port <u16>      Web server port.
            \\--config <str>    Path to config file.
        );

        var diag = clap.Diagnostic{};
        var res = clap.parse(clap.Help, &params, clap.parsers.default, .{
            .diagnostic = &diag,
            .allocator = allocator,
        }) catch |err| {
            diag.report(std.io.getStdErr().writer(), err) catch {};
            return err;
        };
        defer res.deinit();

        if (res.args.help != 0 or
            res.args.port == null or
            res.args.config == null)
        {
            const writer = std.io.getStdErr().writer();
            try writer.writeAll("eink-feed-server\n");
            return clap.help(writer, clap.Help, &params, .{});
        }

        var config_file: std.json.Parsed(ConfigFile) = undefined;
        {
            const data = try std.fs.cwd().readFileAlloc(allocator, res.args.config.?, 1 * 1024 * 1024);
            defer allocator.free(data);
            config_file = try std.json.parseFromSlice(
                ConfigFile,
                allocator,
                data,
                .{ .allocate = .alloc_always, .ignore_unknown_fields = true },
            );
        }
        defer config_file.deinit();

        const config: server.Config = .{
            .web_port = res.args.port.?,
            .channels = config_file.value.channels,
            .clients = config_file.value.clients,
        };
        try server.run(allocator, &config);
    }
}
