// File: /workspace/github_cpp_makefile_star2_O2/bcthomas[P]shrinksam/src/shrinksam.cpp
// Function: main
int main(int argc, char *argv[]) 
{
	locale loc("en_US");
	cout.imbue(loc);

	int c;                            // for getopt
	string input_name;                // input file name
	string shrunk_name;               // output file name
	bool delete_input = false;        // default to no delete
	bool using_stdin = true;          // default to true
	bool using_stdout = true;         // default to true
	bool unpaired = false;            // default to false, assumes paired

	Shrinksam::progname = argv[0];

//	if (argc < 2) {
//		show_usage(EXIT_FAILURE);
//	}

	while(1) {
		static struct option long_options[] =
		{
			{"verbose",      no_argument, 0, 'v'},
			{"version",      no_argument, 0, 'V'},
			{"help",         no_argument, 0, 'h'},
			{"delete-input", no_argument, 0, 'd'},
			{"unpaired",     no_argument, 0, 'u'},
			{"input",        required_argument, 0, 'i'},
			{"shrunk",       required_argument, 0, 'k'},
			{0, 0, 0, 0}
		};

		/* getopt_long stores the option index here. */
		int option_index = 0;

		c = getopt_long(argc, argv, "vVh?dui:k:", long_options, &option_index);

		/* Detect the end of the options. */
		if (c == -1)
			break;

		switch (c) {
			case 'v':
				Shrinksam::verbose_flag = true;
				break;

			case 'V':
				/* version */
				cerr << "Version is " << Shrinksam::version << endl;
				return EXIT_FAILURE;
				break;

			case 'h':
				show_usage(EXIT_FAILURE);
				break;

			case '?':
				/* getopt_long already printed an error message. */
				break;

			case 'i':
				input_name = optarg;
				using_stdin = false;
				break;

			case 'k':
				shrunk_name = optarg;
				using_stdout = false;
				break;

			case 'd':
				delete_input = true;
				break;

			case 'u':
				unpaired = true;
				break;

			default:
				abort ();
		}
	}

	/* check validity of given argument set */
	if (delete_input) {
		if (input_name.empty()) {
			cerr << "Error: Input file name (-i) is required when using -d option." << endl;
			return EXIT_FAILURE;
		}
	}

	if (Shrinksam::verbose_flag) {
		if (using_stdin)
			cerr << "Input is coming from stdin" << endl;
		else
			cerr << "Input is from " << input_name << endl;

		if (using_stdout)
			cerr << "Shrunk SAM output will be to stdout" << endl;
		else
			cerr << "Shrunk SAM output will be in " << shrunk_name << endl;

		if (delete_input)
			cerr << "Input file will be deleted" << endl;
		if (unpaired)
			cerr << "Input is an unpaired SAM file" << endl;
	}

	ifstream input;
	if (using_stdin)
		input.open("/dev/stdin"); // I know - using this code will only work on unix systems
	else
		input.open(input_name);

	ofstream output;
	if (using_stdout)
		output.open("/dev/stdout"); // I know - using this code will only work on unix systems
	else
		output.open(shrunk_name);

	// process the data
	if (unpaired) {
		process_shrunk_unpaired(input,output);
	} else {
		process_shrunk(input,output);
	}

	// delete original file
	if (delete_input) {
		if (Shrinksam::verbose_flag)
			cerr << "Deleting " << input_name << "... " << endl;
		if (remove(input_name.c_str()) != 0)
			cerr << "ERROR: could not delete input file!" << endl;
		else {
			if (Shrinksam::verbose_flag)
				cerr << "Success!" << endl;
		}
	}

	fclose(stderr);
	fclose(stdout);
	fclose(stdin);
	return EXIT_SUCCESS;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x468, %rsp            # imm = 0x468
movq %rsi, %rbx
movl %edi, %ebp
leaq 0x2bb8(%rip), %rsi      # 0x52ab
leaq 0x10(%rsp), %r14
movq %r14, %rdi
callq 0x21b0
movq 0x58b9(%rip), %rsi      # 0x7fc0
movq (%rsi), %rax
addq -0x18(%rax), %rsi
leaq 0x38(%rsp), %rdi
movq %r14, %rdx
callq 0x2090
leaq 0x38(%rsp), %rdi
callq 0x22b0
leaq 0x28(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
xorl %ecx, %ecx
movb %cl, (%rax)
leaq 0x50(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movl $0x0, 0xc(%rsp)
movb %cl, (%rax)
movq (%rbx), %rax
movq %rax, 0x5bcf(%rip)      # 0x8328
movb $0x1, %al
movl %eax, (%rsp)
leaq 0x2b77(%rip), %r14      # 0x52dc
leaq 0x5aa4(%rip), %r15      # 0x8210
leaq 0x60(%rsp), %r12
leaq 0x288c(%rip), %r13      # 0x5004
movb $0x1, %al
movl %eax, 0x4(%rsp)
movl $0x0, 0x8(%rsp)
andl $0x0, 0x60(%rsp)
movl %ebp, %edi
movq %rbx, %rsi
movq %r14, %rdx
movq %r15, %rcx
movq %r12, %r8
callq 0x2330
leal -0x64(%rax), %ecx
cmpl $0x7, %ecx
jbe 0x27be
cmpl $0x3f, %eax
je 0x2786
cmpl $0x75, %eax
je 0x280e
cmpl $0x76, %eax
jne 0x2819
movb $0x1, 0x5b65(%rip)      # 0x8321
jmp 0x2786
movslq (%r13,%rcx,4), %rax
addq %r13, %rax
jmpq *%rax
movb $0x1, %al
movl %eax, 0xc(%rsp)
jmp 0x2786
movq 0x57d1(%rip), %rax      # 0x7fa8
movq (%rax), %rsi
leaq 0x40(%rsp), %rdi
callq 0x23b0
movl $0x0, 0x4(%rsp)
jmp 0x2786
movq 0x57b3(%rip), %rax      # 0x7fa8
movq (%rax), %rsi
leaq 0x18(%rsp), %rdi
callq 0x23b0
movl $0x0, (%rsp)
jmp 0x2786
movb $0x1, %al
movl %eax, 0x8(%rsp)
jmp 0x2786
cmpl $-0x1, %eax
je 0x2853
cmpl $0x56, %eax
jne 0x2b07
movq 0x57c2(%rip), %rdi      # 0x7ff0
leaq 0x2ab2(%rip), %rsi      # 0x52e7
callq 0x2210
movq 0x59bf(%rip), %rsi      # 0x8200
movq %rax, %rdi
callq 0x2210
movq %rax, %rdi
callq 0x2110
jmp 0x2881
cmpq $0x0, 0x20(%rsp)
sete %al
movl 0xc(%rsp), %ebx
andb %bl, %al
cmpb $0x1, %al
jne 0x2889
movq 0x5783(%rip), %rdi      # 0x7ff0
leaq 0x2a7f(%rip), %rsi      # 0x52f3
callq 0x2210
movq %rax, %rdi
callq 0x2110
pushq $0x1
popq %rbx
jmp 0x2ad5
cmpb $0x1, 0x5a91(%rip)      # 0x8321
movl 0x8(%rsp), %ebp
movl 0x4(%rsp), %r14d
movl (%rsp), %r15d
jne 0x296a
testb $0x1, %r15b
je 0x28be
movq 0x5740(%rip), %rdi      # 0x7ff0
leaq 0x2a7a(%rip), %rsi      # 0x5331
callq 0x2210
jmp 0x28de
movq 0x572b(%rip), %rdi      # 0x7ff0
leaq 0x2a80(%rip), %rsi      # 0x534c
callq 0x2210
leaq 0x18(%rsp), %rsi
movq %rax, %rdi
callq 0x2200
movq %rax, %rdi
callq 0x2110
testb $0x1, %r14b
je 0x2901
movq 0x56fd(%rip), %rdi      # 0x7ff0
leaq 0x2a61(%rip), %rsi      # 0x535b
callq 0x2210
jmp 0x2921
movq 0x56e8(%rip), %rdi      # 0x7ff0
leaq 0x2a70(%rip), %rsi      # 0x537f
callq 0x2210
leaq 0x40(%rsp), %rsi
movq %rax, %rdi
callq 0x2200
movq %rax, %rdi
callq 0x2110
testb $0x1, %bl
je 0x2949
movq 0x56bb(%rip), %rdi      # 0x7ff0
leaq 0x2a61(%rip), %rsi      # 0x539d
callq 0x2210
movq %rax, %rdi
callq 0x2110
testb $0x1, %bpl
je 0x296a
movq 0x569a(%rip), %rdi      # 0x7ff0
leaq 0x2a5b(%rip), %rsi      # 0x53b8
callq 0x2210
movq %rax, %rdi
callq 0x2110
leaq 0x60(%rsp), %rdi
callq 0x2260
testb $0x1, %r15b
je 0x2990
leaq 0x2a55(%rip), %rsi      # 0x53d6
leaq 0x60(%rsp), %rdi
pushq $0x8
popq %rdx
callq 0x2170
jmp 0x29a2
leaq 0x60(%rsp), %rdi
leaq 0x18(%rsp), %rsi
pushq $0x8
popq %rdx
callq 0x21e0
leaq 0x268(%rsp), %rdi
callq 0x2350
testb $0x1, %r14b
je 0x29ce
leaq 0x2a25(%rip), %rsi      # 0x53e1
leaq 0x268(%rsp), %rdi
pushq $0x10
popq %rdx
callq 0x2040
jmp 0x29e3
leaq 0x268(%rsp), %rdi
leaq 0x40(%rsp), %rsi
pushq $0x10
popq %rdx
callq 0x2100
testb $0x1, %bpl
je 0x29fd
leaq 0x60(%rsp), %rdi
leaq 0x268(%rsp), %rsi
callq 0x2e64
jmp 0x2a0f
leaq 0x60(%rsp), %rdi
leaq 0x268(%rsp), %rsi
callq 0x2c3d
testb $0x1, %bl
je 0x2a8f
cmpb $0x1, 0x5906(%rip)      # 0x8321
jne 0x2a54
movq 0x55cc(%rip), %rdi      # 0x7ff0
leaq 0x29c2(%rip), %rsi      # 0x53ed
callq 0x2210
leaq 0x18(%rsp), %rsi
movq %rax, %rdi
callq 0x2200
leaq 0x29b3(%rip), %rsi      # 0x53f7
movq %rax, %rdi
callq 0x2210
movq %rax, %rdi
callq 0x2110
movq 0x18(%rsp), %rdi
callq 0x2390
testl %eax, %eax
je 0x2a6b
leaq 0x2993(%rip), %rsi      # 0x53fc
jmp 0x2a7b
cmpb $0x1, 0x58af(%rip)      # 0x8321
jne 0x2a8f
leaq 0x29a5(%rip), %rsi      # 0x5420
movq 0x556e(%rip), %rdi      # 0x7ff0
callq 0x2210
movq %rax, %rdi
callq 0x2110
movq 0x5532(%rip), %rax      # 0x7fc8
movq (%rax), %rdi
callq 0x2220
movq 0x54f3(%rip), %rax      # 0x7f98
movq (%rax), %rdi
callq 0x2220
movq 0x5504(%rip), %rax      # 0x7fb8
movq (%rax), %rdi
callq 0x2220
leaq 0x268(%rsp), %rdi
callq 0x22f0
leaq 0x60(%rsp), %rdi
callq 0x2080
xorl %ebx, %ebx
leaq 0x40(%rsp), %rdi
callq 0x20f0
leaq 0x18(%rsp), %rdi
callq 0x20f0
leaq 0x10(%rsp), %rdi
callq 0x22b0
movl %ebx, %eax
addq $0x468, %rsp            # imm = 0x468
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x2150
pushq $0x1
popq %rdi
callq 0x251c
jmp 0x2b16
movq %rax, %rbx
jmp 0x2b2d
jmp 0x2b42
movq %rax, %rbx
leaq 0x268(%rsp), %rdi
callq 0x22f0
leaq 0x60(%rsp), %rdi
callq 0x2080
jmp 0x2b45
movq %rax, %rbx
jmp 0x2b59
jmp 0x2b42
jmp 0x2b42
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x20f0
leaq 0x18(%rsp), %rdi
callq 0x20f0
leaq 0x10(%rsp), %rdi
callq 0x22b0
movq %rbx, %rdi
callq 0x2370
nop