const std = @import("std");

const MaxFileDepth: u32 = 20;

fn StrConcat(Allocator: std.mem.Allocator, StrLeft: []const u8, StrRight: []const u8) ![]u8 {
    var StringBuilder: []u8 = undefined;
    StringBuilder = try Allocator.alloc(u8, StrLeft.len + StrRight.len);
    std.mem.copyForwards(u8, StringBuilder, StrLeft);
    std.mem.copyForwards(u8, StringBuilder[StrLeft.len..], StrRight);
    return StringBuilder;
}

pub fn GetFilePathRelative(Allocator: std.mem.Allocator, FilePath: []const u8) ![]u8 {
    // Load Lua Main Funct
    const ExePath = try std.fs.selfExeDirPathAlloc(Allocator);
    defer Allocator.free(ExePath);

    // Get the full path
    const FullPath = try StrConcat( Allocator, ExePath, FilePath );
    defer Allocator.free(FullPath);

    // Calculate relative paths by traversing the path and going back up a link when it sees the '..'
    var PathSteps: [MaxFileDepth][]u8 = undefined;
    var LetterIndex: u16 = 0;
    var StartIndex: u16 = 0;
    var ListIndex: u16 = 0;
    for (FullPath) |cur| {
        if ((cur == '/' or cur == '\\') and LetterIndex != 0){
            const subStr = FullPath[StartIndex..LetterIndex];
            if (std.mem.eql(u8, subStr, "/..") or std.mem.eql(u8, subStr, "\\..")){
                ListIndex -= 1;
            }else{
                PathSteps[ListIndex] = subStr;
                ListIndex += 1;
            }
            StartIndex = LetterIndex;
        }
        LetterIndex += 1;
    }
    PathSteps[ListIndex] = FullPath[StartIndex..LetterIndex];
    ListIndex += 1;

    // Concat all the strings together back into a path string
    LetterIndex = 0;
    var returnPath: []u8 = "";
    while (LetterIndex < ListIndex){
        const temp = try StrConcat(Allocator, returnPath, PathSteps[LetterIndex]);
        Allocator.free(returnPath);
        returnPath = temp;
        LetterIndex += 1;
    }

    return returnPath;
}

pub fn FileRead(Allocator: std.mem.Allocator, AbsolutePath: []const u8) ![]u8 {
    var file = try std.fs.cwd().openFile(AbsolutePath, .{});
    defer file.close();

    var bufReader = std.io.bufferedReader(file.reader());
    var inStream = bufReader.reader();

    const FileText = try inStream.readAllAlloc(Allocator, 10000);
    
    return FileText;
}