/** @file */
#include "exec.h"
#include "disk.h"
#include <string.h>

int do_cd(disk *d, char *path) {
  char full_path[1024] = {0};

  format_path(full_path, path, 1024);

  char *path_tmp = strdup(full_path);
  int dir_index = 0;
  char *token = strtok(path_tmp, "/");

  while (token != NULL) {
    dir_index = find_dir_inode_by_name(token, dir_index, d);

    if (dir_index == -1 || d->inodes[dir_index].filetype != TYPE_DIRECTORY) {
      dprintf(STDERR_FILENO, "cd: invalid path: %s\n", token);
      free(path_tmp);
      return -1;
    }
    token = strtok(NULL, "/");
  }

  canonicalize_path(full_path);

  set_env_value("PWD", full_path);

  free(path_tmp);
  return 1;
}

#include "env.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int do_echo(char **args) {
  if (args[0] == NULL) {
    printf("\n");
    return 1;
  }

  char result[4096] = {0};
  int pos = 0;

  for (int i = 0; args[i] != NULL; i++) {
    char *word = args[i];

    for (int j = 0; word[j] != '\0'; j++) {
      if (word[j] == '$' && word[j + 1] != '\0') {
        j++;
        int start = j;

        while (word[j] != '\0' && (isalnum(word[j]) || word[j] == '_')) {
          j++;
        }

        int len = j - start;
        if (len > 0) {
          char key[64];
          strncpy(key, &word[start], len);
          key[len] = '\0';

          char *val = get_env_value(key);
          if (val != NULL) {
            int val_len = strlen(val);
            strcpy(&result[pos], val);
            pos += val_len;
          }
        }
        j--;
      } else {
        result[pos++] = word[j];
      }
    }

    if (args[i + 1] != NULL) {
      result[pos++] = ' ';
    }
  }

  result[pos] = '\0';
  printf("%s\n", result);
  return 1;
}

int child_process_job(disk *d, char **args) {
  if (strcmp("ls", args[0]) == 0) {
    return do_ls(d, args[1]);
  } else if (strcmp("mkdir", args[0]) == 0) {
    return do_mkdir(d, args[1]);
  } else if (strcmp("touch", args[0]) == 0) {
    return do_touch(d, args[1]);
  } else if (strcmp("df", args[0]) == 0) {
    return do_df(d);
  } else {
    dprintf(STDERR_FILENO, "%s: no such command\n", args[0]);
  }
  return 1;
}

int execute_cmd(disk *d, char **args) {
  if (strcmp(args[0], "cd") == 0) {
    return do_cd(d, args[1]);
  } else if (strcmp(args[0], "echo") == 0) {
    return do_echo(&args[1]);
  }

  int pid = fork();

  if (pid == 1) {
    return -1;
  }

  if (pid == 0) {
    return child_process_job(d, args);
  } else {
    int status;
    waitpid(pid, &status, WUNTRACED);
  }
  return 1;
}