// File: WShabti-Team[P]WShabtiPict/wshabtilib/case-test-generator/case-test-generator.cpp
// Function: test_generator(int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
void test_generator(int k_degree, string input_file, string output_file)
{
//----------------------------------------------------------------------------------------------------------------------------------------------------
  	
  	//FILE CONFIGURATION

  	std::ofstream test_case_output_file;

  	test_case_output_file.open(output_file, std::ios_base::out);

//----------------------------------------------------------------------------------------------------------------------------------------------------
  	
  	//PICT CONFIGURATION

    PICT_RET_CODE ret = PICT_SUCCESS;
    PICT_HANDLE task = PictCreateTask();
    PICT_HANDLE model = PictCreateModel();
    PictSetRootModel( task, model );

//----------------------------------------------------------------------------------------------------------------------------------------------------

    //CREATE MODEL

    vector<vector<string>> params_matrix;
    vector<vector<string>> constraints_matrix;
    
    input_parser(input_file, params_matrix, constraints_matrix);

    int number_of_parameters = params_matrix.size();
    PICT_HANDLE* parameters = new PICT_HANDLE[number_of_parameters];

    //Iterate on number of lines to get parameters 
    for(int index = 0; index<number_of_parameters; index++)
    {
        parameters[index] = PictAddParameter( model, params_matrix[index].size(), k_degree );
    }

//----------------------------------------------------------------------------------------------------------------------------------------------------
    
    //ADD CONSTRAINTS

    int number_of_constraints = constraints_matrix.size();
    PICT_EXCLUSION_ITEM** constraints = new PICT_EXCLUSION_ITEM*[number_of_constraints];

    int exclusions_count;
    int number_of_exclusion;
    for(int i = 0; i<number_of_constraints; i++)
    {
        exclusions_count = constraints_matrix[i].size();
    
        for(int j = 0; j < constraints_matrix[i].size(); j++)
        {
            if(constraints_matrix[i][j].compare("*") == 0 )
            {
                exclusions_count--;
            }
        }
        constraints[i] = new PICT_EXCLUSION_ITEM[exclusions_count];

        number_of_exclusion = exclusions_count;        

        for(int j = 0; j < constraints_matrix[i].size(); j++)
        {
            if( constraints_matrix[i][j].compare("*") != 0 )
            {
                constraints[i][exclusions_count-1].Parameter = parameters[j]; 
                constraints[i][exclusions_count-1].ValueIndex = position_in_vector(params_matrix[j], constraints_matrix[i][j]);                //params_matrix[j] -> vettore
                exclusions_count--; 
            }
        }
    
        PictAddExclusion( task, constraints[i], number_of_exclusion);
    }

//----------------------------------------------------------------------------------------------------------------------------------------------------

    //GENERATE RESULTS
    ret = PictGenerate( task );
    PICT_RESULT_ROW row = PictAllocateResultBuffer( task );
    size_t paramCount = PictGetTotalParameterCount( task );
    PictResetResultFetching( task );

//----------------------------------------------------------------------------------------------------------------------------------------------------

    //SAVE RESULTS 
    bool keep_reading = PictGetNextResultRow( task, row );
    while(keep_reading)
    {   
        for( size_t index = 0; index < paramCount-1; ++index )
        {
        	test_case_output_file << params_matrix[index][row[index]] << ",";
        }
        test_case_output_file << params_matrix[paramCount-1][row[paramCount-1]];

        keep_reading = PictGetNextResultRow( task, row );

        if(keep_reading == true)
        {
            test_case_output_file << endl;
        }
    }

//----------------------------------------------------------------------------------------------------------------------------------------------------

    //PICT DELETE 

    PictFreeResultBuffer( row );
    if( model != NULL )    {    PictDeleteModel( model ); }
    if( task != NULL )     {    PictDeleteTask( task );   }

//----------------------------------------------------------------------------------------------------------------------------------------------------

    //FILE CLOSING
    test_case_output_file.close();

//----------------------------------------------------------------------------------------------------------------------------------------------------
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3b0, %rsp            # imm = 0x3B0
movq %rsi, -0x330(%rbp)
movq %rdx, -0x320(%rbp)
movl %edi, -0x4(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
leaq -0x218(%rbp), %rdi
movq %rdi, -0x328(%rbp)
callq 0x7970
movq -0x328(%rbp), %rdi
movq -0x320(%rbp), %rsi
movl $0x10, %edx
callq 0x72d0
jmp 0x5f571
movl $0x0, -0x228(%rbp)
callq 0x2f180
movq %rax, -0x338(%rbp)
jmp 0x5f589
movq -0x338(%rbp), %rax
movq %rax, -0x230(%rbp)
xorl %edi, %edi
callq 0x2f8a0
movq %rax, -0x340(%rbp)
jmp 0x5f5a7
movq -0x340(%rbp), %rax
movq %rax, -0x238(%rbp)
movq -0x230(%rbp), %rdi
movq -0x238(%rbp), %rsi
callq 0x2f1e0
jmp 0x5f5ca
leaq -0x250(%rbp), %rdi
callq 0x5fd70
leaq -0x268(%rbp), %rdi
callq 0x5fd70
movq -0x330(%rbp), %rsi
leaq -0x288(%rbp), %rdi
callq 0x7270
jmp 0x5f5f7
leaq -0x288(%rbp), %rdi
leaq -0x250(%rbp), %rsi
leaq -0x268(%rbp), %rdx
callq 0x33a10
jmp 0x5f613
leaq -0x288(%rbp), %rdi
callq 0x73e0
leaq -0x250(%rbp), %rdi
callq 0x35750
movl %eax, -0x28c(%rbp)
movslq -0x28c(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x7040
movq %rax, -0x348(%rbp)
jmp 0x5f65c
movq -0x348(%rbp), %rax
movq %rax, -0x298(%rbp)
movl $0x0, -0x29c(%rbp)
movl -0x29c(%rbp), %eax
cmpl -0x28c(%rbp), %eax
jge 0x5f74c
movq -0x238(%rbp), %rax
movq %rax, -0x358(%rbp)
movslq -0x29c(%rbp), %rsi
leaq -0x250(%rbp), %rdi
callq 0x345b0
movq %rax, %rdi
callq 0x32c20
movq -0x358(%rbp), %rdi
movq %rax, %rsi
movl -0x4(%rbp), %edx
xorl %eax, %eax
movl %eax, %ecx
callq 0x2f970
movq %rax, -0x350(%rbp)
jmp 0x5f6ce
movq -0x350(%rbp), %rdx
movq -0x298(%rbp), %rax
movslq -0x29c(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movl -0x29c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x29c(%rbp)
jmp 0x5f674
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x5fd58
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x5fd40
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x288(%rbp), %rdi
callq 0x73e0
jmp 0x5fd40
leaq -0x268(%rbp), %rdi
callq 0x35750
movl %eax, -0x2a0(%rbp)
movslq -0x2a0(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x7040
movq %rax, -0x360(%rbp)
jmp 0x5f789
movq -0x360(%rbp), %rax
movq %rax, -0x2a8(%rbp)
movl $0x0, -0x2b4(%rbp)
movl -0x2b4(%rbp), %eax
cmpl -0x2a0(%rbp), %eax
jge 0x5fadb
movslq -0x2b4(%rbp), %rsi
leaq -0x268(%rbp), %rdi
callq 0x345b0
movq %rax, %rdi
callq 0x32c20
movl %eax, -0x2ac(%rbp)
movl $0x0, -0x2b8(%rbp)
movslq -0x2b8(%rbp), %rax
movq %rax, -0x368(%rbp)
movslq -0x2b4(%rbp), %rsi
leaq -0x268(%rbp), %rdi
callq 0x345b0
movq %rax, %rdi
callq 0x32c20
movq %rax, %rcx
movq -0x368(%rbp), %rax
cmpq %rcx, %rax
jae 0x5f871
movslq -0x2b4(%rbp), %rsi
leaq -0x268(%rbp), %rdi
callq 0x345b0
movq %rax, %rdi
movslq -0x2b8(%rbp), %rsi
callq 0x32c40
movq %rax, %rdi
leaq 0x655a(%rip), %rsi      # 0x65d9c
callq 0x7190
cmpl $0x0, %eax
jne 0x5f85b
movl -0x2ac(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x2ac(%rbp)
jmp 0x5f85d
movl -0x2b8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2b8(%rbp)
jmp 0x5f7de
movslq -0x2ac(%rbp), %rax
movl $0x10, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x7040
movq %rax, -0x370(%rbp)
jmp 0x5f89c
movq -0x370(%rbp), %rdx
movq -0x2a8(%rbp), %rax
movslq -0x2b4(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movl -0x2ac(%rbp), %eax
movl %eax, -0x2b0(%rbp)
movl $0x0, -0x2bc(%rbp)
movslq -0x2bc(%rbp), %rax
movq %rax, -0x378(%rbp)
movslq -0x2b4(%rbp), %rsi
leaq -0x268(%rbp), %rdi
callq 0x345b0
movq %rax, %rdi
callq 0x32c20
movq %rax, %rcx
movq -0x378(%rbp), %rax
cmpq %rcx, %rax
jae 0x5fa9e
movslq -0x2b4(%rbp), %rsi
leaq -0x268(%rbp), %rdi
callq 0x345b0
movq %rax, %rdi
movslq -0x2bc(%rbp), %rsi
callq 0x32c40
movq %rax, %rdi
leaq 0x6469(%rip), %rsi      # 0x65d9c
callq 0x7190
cmpl $0x0, %eax
je 0x5fa88
movq -0x298(%rbp), %rax
movslq -0x2bc(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
movq -0x2a8(%rbp), %rax
movslq -0x2b4(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl -0x2ac(%rbp), %ecx
decl %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
movq %rdx, (%rax,%rcx)
movslq -0x2bc(%rbp), %rsi
leaq -0x250(%rbp), %rdi
callq 0x345b0
movq %rax, %rsi
leaq -0x2d8(%rbp), %rdi
callq 0x47fc0
jmp 0x5f99c
movslq -0x2b4(%rbp), %rsi
leaq -0x268(%rbp), %rdi
callq 0x345b0
movq %rax, %rdi
movslq -0x2bc(%rbp), %rsi
callq 0x32c40
movq %rax, %rsi
leaq -0x2f8(%rbp), %rdi
callq 0x7270
jmp 0x5f9cf
leaq -0x2d8(%rbp), %rdi
leaq -0x2f8(%rbp), %rsi
callq 0x32a40
movl %eax, -0x37c(%rbp)
jmp 0x5f9ea
movl -0x37c(%rbp), %eax
movslq %eax, %rcx
movq -0x2a8(%rbp), %rax
movslq -0x2b4(%rbp), %rdx
movq (%rax,%rdx,8), %rax
movl -0x2ac(%rbp), %edx
subl $0x1, %edx
movslq %edx, %rdx
shlq $0x4, %rdx
addq %rdx, %rax
movq %rcx, 0x8(%rax)
leaq -0x2f8(%rbp), %rdi
callq 0x73e0
leaq -0x2d8(%rbp), %rdi
callq 0x32bc0
movl -0x2ac(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x2ac(%rbp)
jmp 0x5fa88
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x5fa77
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x2f8(%rbp), %rdi
callq 0x73e0
leaq -0x2d8(%rbp), %rdi
callq 0x32bc0
jmp 0x5fd40
jmp 0x5fa8a
movl -0x2bc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2bc(%rbp)
jmp 0x5f8cb
movq -0x230(%rbp), %rdi
movq -0x2a8(%rbp), %rax
movslq -0x2b4(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
movslq -0x2b0(%rbp), %rdx
callq 0x2f210
jmp 0x5fac5
jmp 0x5fac7
movl -0x2b4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2b4(%rbp)
jmp 0x5f7a1
movq -0x230(%rbp), %rdi
callq 0x2f520
movl %eax, -0x380(%rbp)
jmp 0x5faef
movl -0x380(%rbp), %eax
movl %eax, -0x228(%rbp)
movq -0x230(%rbp), %rdi
callq 0x2f6f0
movq %rax, -0x388(%rbp)
jmp 0x5fb10
movq -0x388(%rbp), %rax
movq %rax, -0x300(%rbp)
movq -0x230(%rbp), %rdi
callq 0x2fc10
movq %rax, -0x390(%rbp)
jmp 0x5fb33
movq -0x390(%rbp), %rax
movq %rax, -0x308(%rbp)
movq -0x230(%rbp), %rdi
callq 0x2f750
jmp 0x5fb4f
movq -0x230(%rbp), %rdi
movq -0x300(%rbp), %rsi
callq 0x2f780
movq %rax, -0x398(%rbp)
jmp 0x5fb6b
movq -0x398(%rbp), %rax
cmpq $0x0, %rax
setne %al
andb $0x1, %al
movb %al, -0x309(%rbp)
testb $0x1, -0x309(%rbp)
je 0x5fcc3
movq $0x0, -0x318(%rbp)
movq -0x318(%rbp), %rax
movq -0x308(%rbp), %rcx
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0x5fc23
movq -0x318(%rbp), %rsi
leaq -0x250(%rbp), %rdi
callq 0x345b0
movq %rax, %rdi
movq -0x300(%rbp), %rax
movq -0x318(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x32c40
movq %rax, %rsi
leaq -0x218(%rbp), %rdi
callq 0x7560
movq %rax, -0x3a0(%rbp)
jmp 0x5fbf5
movq -0x3a0(%rbp), %rdi
leaq 0x606f(%rip), %rsi      # 0x65c72
callq 0x75d0
jmp 0x5fc0a
jmp 0x5fc0c
movq -0x318(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x318(%rbp)
jmp 0x5fb99
movq -0x308(%rbp), %rsi
decq %rsi
leaq -0x250(%rbp), %rdi
callq 0x345b0
movq %rax, %rdi
movq -0x300(%rbp), %rax
movq -0x308(%rbp), %rcx
movq -0x8(%rax,%rcx,8), %rsi
callq 0x32c40
movq %rax, %rsi
leaq -0x218(%rbp), %rdi
callq 0x7560
jmp 0x5fc65
movq -0x230(%rbp), %rdi
movq -0x300(%rbp), %rsi
callq 0x2f780
movq %rax, -0x3a8(%rbp)
jmp 0x5fc81
movq -0x3a8(%rbp), %rax
cmpq $0x0, %rax
setne %al
andb $0x1, %al
movb %al, -0x309(%rbp)
movb -0x309(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x5fcbe
movq 0x322b2(%rip), %rsi     # 0x91f60
leaq -0x218(%rbp), %rdi
callq 0x7640
jmp 0x5fcbc
jmp 0x5fcbe
jmp 0x5fb81
movq -0x300(%rbp), %rdi
callq 0x2f730
jmp 0x5fcd1
cmpq $0x0, -0x238(%rbp)
je 0x5fceb
movq -0x238(%rbp), %rdi
callq 0x2fce0
jmp 0x5fce9
jmp 0x5fceb
cmpq $0x0, -0x230(%rbp)
je 0x5fd05
movq -0x230(%rbp), %rdi
callq 0x2f860
jmp 0x5fd03
jmp 0x5fd05
leaq -0x218(%rbp), %rdi
callq 0x7810
jmp 0x5fd13
leaq -0x268(%rbp), %rdi
callq 0x5fd90
leaq -0x250(%rbp), %rdi
callq 0x5fd90
leaq -0x218(%rbp), %rdi
callq 0x7850
addq $0x3b0, %rsp            # imm = 0x3B0
popq %rbp
retq
leaq -0x268(%rbp), %rdi
callq 0x5fd90
leaq -0x250(%rbp), %rdi
callq 0x5fd90
leaq -0x218(%rbp), %rdi
callq 0x7850
movq -0x220(%rbp), %rdi
callq 0x79d0