// File: AndreiBarsan[P]uShell/shell.cc
// Function: microshell::core::Shell::parse_command(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::shared_ptr<microshell::core::Command>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*) const
bool Shell::parse_command(const string& command_text,
                          shared_ptr<Command> &command,
                          string *error) const {
  // TODO(andrei) YACC this.
  // TODO(andrei) Customizable IFS variable.
  vector<string> argv = util::split(command_text, ' ');

  // Perform expansion for every parameter.
  for(string& arg : argv) {
    arg = expand(arg);
  }

  const string& program_name = argv[0];

  if(is_builtin(argv[0])) {
    command = construct_builtin(argv);
  }
  else {
    // If the path actually points to a directory, we want to catch that.
    string full_path = resolve_path(program_name);
    if (util::is_directory(full_path)) {
      // TODO(andrei) zsh-like auto-cd functionality could go here.
      *error = "Cannot execute [" + argv[0] + "]. It's a directory.";
      return false;
    }

    string binary_path;
    if(resolve_binary_name(argv[0], &binary_path)) {
      argv[0] = binary_path;
      command = make_shared<DiskCommand>(new DiskCommand(argv));
    } else {
      *error = "Command not found: [" + argv[0] + "]";
      return false;
    }
  }

  return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1c0, %rsp            # imm = 0x1C0
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x190(%rbp)
movq -0x18(%rbp), %rsi
leaq -0x40(%rbp), %rdi
movl $0x20, %edx
callq 0x203d0
leaq -0x40(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
callq 0x6910
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rdi
callq 0x6980
movq %rax, -0x58(%rbp)
leaq -0x50(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x1c370
testb $0x1, %al
jne 0x1ae5d
jmp 0x1aeb8
leaq -0x50(%rbp), %rdi
callq 0x1c3b0
movq -0x190(%rbp), %rsi
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rdx
leaq -0x80(%rbp), %rdi
callq 0x1b2a0
jmp 0x1ae80
movq -0x60(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x5320
leaq -0x80(%rbp), %rdi
callq 0x5190
leaq -0x50(%rbp), %rdi
callq 0x1c3d0
jmp 0x1ae4a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x1b255
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0x1a0(%rbp)
leaq -0x40(%rbp), %rdi
movq %rdi, -0x1a8(%rbp)
callq 0x6b60
movq -0x1a8(%rbp), %rdi
movq -0x1a0(%rbp), %rsi
movq %rax, -0x98(%rbp)
callq 0x6b60
movq -0x190(%rbp), %rdi
movq %rax, %rsi
callq 0x1b6d0
movb %al, -0x191(%rbp)
jmp 0x1af04
movb -0x191(%rbp), %al
testb $0x1, %al
jne 0x1af10
jmp 0x1af4a
movq -0x190(%rbp), %rsi
leaq -0xa8(%rbp), %rdi
leaq -0x40(%rbp), %rdx
callq 0x1b700
jmp 0x1af29
movq -0x20(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x1c3f0
leaq -0xa8(%rbp), %rdi
callq 0x1c420
jmp 0x1b230
movq -0x190(%rbp), %rsi
movq -0x98(%rbp), %rdx
leaq -0xc8(%rbp), %rdi
callq 0x1b360
jmp 0x1af66
leaq -0xc8(%rbp), %rdi
callq 0x208e0
movb %al, -0x1a9(%rbp)
jmp 0x1af7a
movb -0x1a9(%rbp), %al
testb $0x1, %al
jne 0x1af89
jmp 0x1b03f
xorl %eax, %eax
movl %eax, %esi
leaq -0x40(%rbp), %rdi
callq 0x6b60
movq %rax, %rdx
leaq 0x856e(%rip), %rsi      # 0x2350e
leaq -0x108(%rbp), %rdi
callq 0x6a50
jmp 0x1afae
leaq 0x856a(%rip), %rdx      # 0x2351f
leaq -0xe8(%rbp), %rdi
leaq -0x108(%rbp), %rsi
callq 0x69b0
jmp 0x1afca
movq -0x28(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x5320
leaq -0xe8(%rbp), %rdi
callq 0x5190
leaq -0x108(%rbp), %rdi
callq 0x5190
movb $0x0, -0x1(%rbp)
movl $0x1, -0x10c(%rbp)
jmp 0x1b1fc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x1b222
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x108(%rbp), %rdi
callq 0x5190
jmp 0x1b222
leaq -0x130(%rbp), %rdi
movq %rdi, -0x1b8(%rbp)
callq 0x5370
xorl %eax, %eax
movl %eax, %esi
leaq -0x40(%rbp), %rdi
callq 0x6b60
movq -0x190(%rbp), %rdi
movq -0x1b8(%rbp), %rdx
movq %rax, %rsi
callq 0x1b740
movb %al, -0x1aa(%rbp)
jmp 0x1b07d
movb -0x1aa(%rbp), %al
testb $0x1, %al
jne 0x1b08c
jmp 0x1b14d
xorl %eax, %eax
movl %eax, %esi
leaq -0x40(%rbp), %rdi
callq 0x6b60
movq %rax, %rdi
leaq -0x130(%rbp), %rsi
callq 0x5060
jmp 0x1b0aa
movl $0x20, %edi
callq 0x5280
movq %rax, -0x1c0(%rbp)
jmp 0x1b0bd
movq -0x1c0(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x1c4b0
jmp 0x1b0cf
movq -0x1c0(%rbp), %rax
movq %rax, -0x148(%rbp)
leaq -0x140(%rbp), %rdi
leaq -0x148(%rbp), %rsi
callq 0x1c440
jmp 0x1b0f2
movq -0x20(%rbp), %rdi
leaq -0x140(%rbp), %rsi
callq 0x1c4f0
leaq -0x140(%rbp), %rdi
callq 0x1c520
jmp 0x1b1e6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x1b216
movq -0x1c0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
callq 0x5250
jmp 0x1b216
xorl %eax, %eax
movl %eax, %esi
leaq -0x40(%rbp), %rdi
callq 0x6b60
movq %rax, %rdx
leaq 0x83d0(%rip), %rsi      # 0x23534
leaq -0x188(%rbp), %rdi
callq 0x6a50
jmp 0x1b172
leaq 0x6ec3(%rip), %rdx      # 0x2203c
leaq -0x168(%rbp), %rdi
leaq -0x188(%rbp), %rsi
callq 0x69b0
jmp 0x1b18e
movq -0x28(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x5320
leaq -0x168(%rbp), %rdi
callq 0x5190
leaq -0x188(%rbp), %rdi
callq 0x5190
movb $0x0, -0x1(%rbp)
movl $0x1, -0x10c(%rbp)
jmp 0x1b1f0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x188(%rbp), %rdi
callq 0x5190
jmp 0x1b216
movl $0x0, -0x10c(%rbp)
leaq -0x130(%rbp), %rdi
callq 0x5190
leaq -0xc8(%rbp), %rdi
callq 0x5190
movl -0x10c(%rbp), %eax
testl %eax, %eax
jne 0x1b23e
jmp 0x1b214
jmp 0x1b230
leaq -0x130(%rbp), %rdi
callq 0x5190
leaq -0xc8(%rbp), %rdi
callq 0x5190
jmp 0x1b255
movb $0x1, -0x1(%rbp)
movl $0x1, -0x10c(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x8660
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x1c0, %rsp            # imm = 0x1C0
popq %rbp
retq
leaq -0x40(%rbp), %rdi
callq 0x8660
movq -0x88(%rbp), %rdi
callq 0x5460
nopw (%rax,%rax)