const std = @import("std");
const print = std.debug.print;
var buffer : [22048]u8 = undefined;

pub fn main() !void
{
    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();
    const allocator = arena.allocator();

    const read_bytes = try readFile("day3.txt");
    const pattern = "mul("; 



    var slice :[]u8= undefined;
    var slice2 :[]u8= undefined;
    slice2 = buffer[0..read_bytes];

    var mulresult : u64 = 0;
    var count : u64 = 0;

    var endpos : usize = 0;
    //var buf : [10]u8 = undefined;
   

    while(slice2.len != 0) : (count += 1)
    {
        print("slice2: {}\n",.{slice2.len});
        while(true)
        {
            var do = std.mem.indexOf(u8,slice2,"do()");
            if(count == 0)
            {
                do = 0;
            }

            const dont = std.mem.indexOf(u8,slice2,"don't()");
             
            if(do == null and dont == null)
            {
                print("last line\n",.{});
                    std.posix.exit(1);
                break;
            }
            if(do) | do2 |
            {
                if(dont) | dont2 |
                {   
                    if(dont2 > do2)
                    {
                        print("endpos{s}  ,endpos{d}\n",.{buffer[endpos..endpos+5],endpos});
                        slice2 = slice2[do2..dont2];
                        endpos = endpos +  dont2 + 7; //absolute pos in buffer
                        break;
                    }
                    else
                    {
                        endpos = endpos + dont2 + 7;
                        slice2 = buffer[endpos..];
                        print("endpos{s}  ,endpos{d}\n",.{buffer[endpos..endpos+5],endpos});
                    }
                }
                else
                {
                    //slice2 = slice2[do2..];
                    print("last line\n",.{});
                    std.posix.exit(1);
                    break;
                }
            }
        }

        slice = slice2;
        while(slice.len != 0)
        {
            //_ = try std.io.getStdIn().reader().readUntilDelimiterOrEof(buf[0..],'\n');
            const first = std.mem.indexOf(u8,slice,pattern);

            var index2 : usize = 0;


            if(first) | index |
            {   
                var num :u64 = 0;
                const len  = try getNum(allocator,slice,index + pattern.len,&num);
                if(len > 0)
                {
                    if(slice[index + pattern.len + len] == ',')
                    {
                        var num2 : u64 = 0;
                        const len2 = try getNum(allocator,slice,index + pattern.len + len + 1,&num2);
                        if(len2 > 0)
                        {
                            //print("num2: {}\n",.{num2});
                            index2 = index + pattern.len + len + len2 + 1;
                            if(slice[index2] == ')')
                            {
                                mulresult = mulresult + (num * num2);
                                if(num > 999 or num2 > 999)
                                {
                                    print("error invalid data to loong number",.{});
                                    std.posix.exit(1);
                                }
                                print("{s}({d},{d})\nmulresult: {d}\n",.{pattern,num,num2,mulresult});
                            }
                            else
                            {
                                index2 = index + 1;
                            }
                        }
                    }
                    else
                    {
                        index2 = index + 1;
                    }
                }
                else
                {
                        print("len: {}\n slice: {s}\n endpos{s}\n",.{len,slice,buffer[endpos-5..endpos]});
                }
                if(slice.len > index2)
                {
                    slice = slice[index2..];
                    //print("slice len: {} \nindex2:{}\n",.{slice.len,index2});
                }
                else
                {
                    break;
                }
            }
            else
            {

                break;
            }
//print("do: {?}, dont(): {?}\nslice.len:{}\n,index2:\n",.{do,dont,slice.len});

        }

        slice2 = buffer[endpos..];
    }
   print("add up muls: {d}\nreadBytes from File: {d}",.{mulresult,read_bytes});    
}

fn getNum(allocator : std.mem.Allocator,buf : []u8,first : usize,parsed : *u64) !usize
{
    var result : []u8 = try allocator.alloc(u8,0);
    var i: u64 = first;
    if(i >= buf.len - 1)
    {
        return 0;
    }

    while(isNumber(buf[i]) == true) : ( i += 1)
        {
            //_ = try std.fmt.bufPrint(&result,"{s}{}",.{temp,buf[i]});
             result = try std.fmt.allocPrint(allocator,"{s}{c}",.{result,buf[i]});
             if(i >=  buf.len-1)
             {
                 return 0;
             }
        }
        print("\n{s}\nlen: {}",.{result,result.len});
        if(result.len > 0)
        {
            parsed.* = try std.fmt.parseUnsigned(u64,result,10);
        }
        else
        {
            return 0;
        }
        defer allocator.free(result);
        return result.len;
}

fn isNumber(number : u8) bool
{
    const numbers = [10]u8{'0','1','2','3','4','5','6','7','8','9'};
    for(numbers) | nbr |
    {
        if(number == nbr)
        {
            return true;
        }
    }
    return false;
}

fn readFile(filename : [] const u8) !usize
{
    const file = try std.fs.cwd().openFile(filename,.{});
    defer file.close();

    const bytes_read = try file.readAll(&buffer);
    return bytes_read;

}

test "search substring"
{
    const pos = std.mem.indexOf(u8,"abcde","ded");
    print("Pos: {?}",.{pos});
}
