// File: dianejdan[P]Eclat/main.cpp
// Function: main
int main(int argc, char* argv[]){

    time_t startT, endT;
    time(&startT); // record start time

    char* filename; // input file name
    int minsup; // min sup
    bool prnt = false; // print or not

    // use getopt to get options and arguments
    int c;
    while((c = getopt(argc, argv, "f:s:p")) != -1){
        switch(c){
            case 'f': // input file
                filename = optarg;
                break;
            case 's': // min sup
                minsup = (int)atof(optarg);
                break;
            case 'p': // print or not
                prnt = true;
                break;
            default: // print usage
                cout << "Usage: \n" << "./main -f input -s minsup [-p]\n"
                     << "(-f input) should be together\n"
                     << "(-s minsup) should be together\n"
                     << "the three argument pairs can be in any order\n";
        }
    }


    DbReader reader; // reader of input file

    // the DbReader class can detect the type of input file, int, char, string
    switch( reader.template_type(filename) ){
        case 1: // int
          {
            cout << "The items are integer.\n";
            PatternStore<int> pS1; // pattern store
            pS1.set_minsup(minsup); // set up min sup
            reader.read_txt(pS1, filename, minsup); // read input and populate single item tid list

            pS1.eclat(pS1.root()); // eclat algorithm
            pS1.display(); // show how many frequent patterns

            if (prnt)
                  pS1.print_patterns(); // if -p is specified, print patterns
            break;
          }
        case 2: // char
          {
            cout << "The items are char.\n";
            PatternStore<char> pS2;
            pS2.set_minsup(minsup);
            reader.read_txt(pS2, filename, minsup);

            pS2.eclat(pS2.root());
            pS2.display();

            if (prnt)
                  pS2.print_patterns();
            break;
          }
        case 3: // string
          {
            cout << "The items are string.\n";
            PatternStore<string> pS3;
            pS3.set_minsup(minsup);
            reader.read_txt(pS3, filename, minsup);

            pS3.eclat(pS3.root());
            pS3.display();

            if (prnt)
                  pS3.print_patterns();
            break;
          }
        default:
            cout << "The format of item in input file cannot be recognized.\n";

    }

    time(&endT);
    cout << "The program takes " << difftime(endT, startT) << " seconds to finish.\n\n"; // output time

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x18(%rbp), %rdi
callq 0x2210
movb $0x0, -0x2d(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0xeaa0(%rip), %rdx      # 0x11004
callq 0x2080
movl %eax, -0x34(%rbp)
cmpl $-0x1, %eax
je 0x2621
movl -0x34(%rbp), %eax
movl %eax, -0x84(%rbp)
subl $0x66, %eax
je 0x259f
jmp 0x2585
movl -0x84(%rbp), %eax
subl $0x70, %eax
je 0x25c7
jmp 0x2592
movl -0x84(%rbp), %eax
subl $0x73, %eax
je 0x25af
jmp 0x25cd
movq 0x17a22(%rip), %rax     # 0x19fc8
movq (%rax), %rax
movq %rax, -0x28(%rbp)
jmp 0x261c
movq 0x17a12(%rip), %rax     # 0x19fc8
movq (%rax), %rdi
callq 0x22d0
cvttsd2si %xmm0, %eax
movl %eax, -0x2c(%rbp)
jmp 0x261c
movb $0x1, -0x2d(%rbp)
jmp 0x261c
movq 0x17a04(%rip), %rdi     # 0x19fd8
leaq 0xea2f(%rip), %rsi      # 0x1100a
callq 0x2220
movq %rax, %rdi
leaq 0xea29(%rip), %rsi      # 0x11013
callq 0x2220
movq %rax, %rdi
leaq 0xea3a(%rip), %rsi      # 0x11033
callq 0x2220
movq %rax, %rdi
leaq 0xea4a(%rip), %rsi      # 0x11052
callq 0x2220
movq %rax, %rdi
leaq 0xea5b(%rip), %rsi      # 0x11072
callq 0x2220
jmp 0x2556
movq -0x28(%rbp), %rsi
leaq -0x35(%rbp), %rdi
callq 0x2810
movl %eax, %ecx
movl %ecx, -0x88(%rbp)
subl $0x1, %eax
je 0x2662
jmp 0x263d
movl -0x88(%rbp), %eax
subl $0x2, %eax
je 0x26d0
jmp 0x264e
movl -0x88(%rbp), %eax
subl $0x3, %eax
je 0x273b
jmp 0x27a6
movq 0x1796f(%rip), %rdi     # 0x19fd8
leaq 0xea30(%rip), %rsi      # 0x110a0
callq 0x2220
leaq -0x50(%rbp), %rdi
callq 0x2a20
movl -0x2c(%rbp), %esi
leaq -0x50(%rbp), %rdi
callq 0x2a90
movq -0x28(%rbp), %rdx
movl -0x2c(%rbp), %ecx
leaq -0x35(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x2ab0
leaq -0x50(%rbp), %rdi
callq 0x31b0
movq %rax, %rsi
leaq -0x50(%rbp), %rdi
callq 0x2f90
leaq -0x50(%rbp), %rdi
callq 0x31d0
testb $0x1, -0x2d(%rbp)
je 0x26cb
leaq -0x50(%rbp), %rdi
callq 0x3220
jmp 0x27b9
movq 0x17901(%rip), %rdi     # 0x19fd8
leaq 0xe9da(%rip), %rsi      # 0x110b8
callq 0x2220
leaq -0x68(%rbp), %rdi
callq 0x32d0
movl -0x2c(%rbp), %esi
leaq -0x68(%rbp), %rdi
callq 0x3340
movq -0x28(%rbp), %rdx
movl -0x2c(%rbp), %ecx
leaq -0x35(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x3360
leaq -0x68(%rbp), %rdi
callq 0x3a60
movq %rax, %rsi
leaq -0x68(%rbp), %rdi
callq 0x3840
leaq -0x68(%rbp), %rdi
callq 0x3a80
testb $0x1, -0x2d(%rbp)
je 0x2739
leaq -0x68(%rbp), %rdi
callq 0x3ad0
jmp 0x27b9
movq 0x17896(%rip), %rdi     # 0x19fd8
leaq 0xe984(%rip), %rsi      # 0x110cd
callq 0x2220
leaq -0x80(%rbp), %rdi
callq 0x3b80
movl -0x2c(%rbp), %esi
leaq -0x80(%rbp), %rdi
callq 0x3bf0
movq -0x28(%rbp), %rdx
movl -0x2c(%rbp), %ecx
leaq -0x35(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x3c10
leaq -0x80(%rbp), %rdi
callq 0x43b0
movq %rax, %rsi
leaq -0x80(%rbp), %rdi
callq 0x4160
leaq -0x80(%rbp), %rdi
callq 0x43d0
testb $0x1, -0x2d(%rbp)
je 0x27a4
leaq -0x80(%rbp), %rdi
callq 0x4420
jmp 0x27b9
movq 0x1782b(%rip), %rdi     # 0x19fd8
leaq 0xe930(%rip), %rsi      # 0x110e4
callq 0x2220
leaq -0x20(%rbp), %rdi
callq 0x2210
movq 0x1780f(%rip), %rdi     # 0x19fd8
leaq 0xe94c(%rip), %rsi      # 0x1111c
callq 0x2220
movq %rax, -0x90(%rbp)
movq -0x20(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x2100
movq -0x90(%rbp), %rdi
callq 0x23d0
movq %rax, %rdi
leaq 0xe930(%rip), %rsi      # 0x1112f
callq 0x2220
xorl %eax, %eax
addq $0x90, %rsp
popq %rbp
retq
nop