// zig fmt: off
const std = @import("std");
const builtin = @import("builtin");
const Allocator = std.mem.Allocator;

const Artificer = @import("artificer");
const Api = @import("artifacts-api");

pub const std_options = .{
    .log_scope_levels = &[_]std.log.ScopeLevel{
        .{ .scope = .api, .level = .info },
        .{ .scope = .artificer, .level = .debug },
    }
};

fn getAPITokenFromArgs(allocator: Allocator) !?[]u8 {
    const args = try std.process.argsAlloc(allocator);
    defer std.process.argsFree(allocator, args);

    if (args.len < 2) {
        return null;
    }

    const filename = args[1];
    const cwd = std.fs.cwd();
    var token_buffer: [256]u8 = undefined;
    const token = try cwd.readFile(filename, &token_buffer);

    return try allocator.dupe(u8, std.mem.trim(u8, token, "\n\t "));
}

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

    const token = (try getAPITokenFromArgs(allocator)) orelse return error.MissingToken;
    defer allocator.free(token);

    var store = try Api.Store.init(allocator);
    defer store.deinit(allocator);

    var server = try Api.Server.init(allocator, &store);
    defer server.deinit();

    try server.setToken(token);

    std.log.info("Prefetching server data", .{});
    {
        const cwd_path = try std.fs.cwd().realpathAlloc(allocator, ".");
        defer allocator.free(cwd_path);

        const cache_path = try std.fs.path.resolve(allocator, &.{ cwd_path, "./api-store.bin" });
        defer allocator.free(cache_path);

        // TODO: Don't prefetch images
        try server.prefetchCached(allocator, cache_path);
    }

    const character_id = (try server.getCharacter("Blondie")).?;

    var artificer = try Artificer.init(allocator, &server, character_id);
    defer artificer.deinit(allocator);

    // _ = try artificer.appendGoal(Artificer.Goal{
    //     .gather = .{
    //         .item = store.items.getId("sap").?,
    //         .quantity = 1
    //     }
    // });

    _ = try artificer.appendGoal(Artificer.Goal{
        .craft = .{
            .item = store.items.getId("copper").?,
            .quantity = 2
        }
    });

    std.log.info("Starting main loop", .{});
    try artificer.runUntilGoalsComplete();
}
