/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <errno.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/statfs.h>
#include <unistd.h>
#include <dirent.h>
#include <ctype.h>

#include "applypatch.h"

static int EliminateOpenFiles(char** files, int file_count) {
  DIR* d;
  struct dirent* de;
  d = opendir("/proc");
  if (d == NULL) {
    printf("error opening /proc: %s\n", strerror(errno));
    return -1;
  }
  while ((de = readdir(d)) != 0) {
    int i;
    for (i = 0; de->d_name[i] != '\0' && isdigit(de->d_name[i]); ++i);
    if (de->d_name[i]) continue;

    // de->d_name[i] is numeric

    char path[FILENAME_MAX];
    strcpy(path, "/proc/");
    strcat(path, de->d_name);
    strcat(path, "/fd/");

    DIR* fdd;
    struct dirent* fdde;
    fdd = opendir(path);
    if (fdd == NULL) {
      printf("error opening %s: %s\n", path, strerror(errno));
      continue;
    }
    while ((fdde = readdir(fdd)) != 0) {
      char fd_path[FILENAME_MAX];
      char link[FILENAME_MAX];
      strcpy(fd_path, path);
      strcat(fd_path, fdde->d_name);

      int count;
      count = readlink(fd_path, link, sizeof(link)-1);
      if (count >= 0) {
        link[count] = '\0';

        // This is inefficient, but it should only matter if there are
        // lots of files in /cache, and lots of them are open (neither
        // of which should be true, especially in recovery).
        if (strncmp(link, "/cache/", 7) == 0) {
          int j;
          for (j = 0; j < file_count; ++j) {
            if (files[j] && strcmp(files[j], link) == 0) {
              printf("%s is open by %s\n", link, de->d_name);
              free(files[j]);
              files[j] = NULL;
            }
          }
        }
      }
    }
    closedir(fdd);
  }
  closedir(d);

  return 0;
}

int FindExpendableFiles(char*** names, int* entries) {
  DIR* d;
  struct dirent* de;
  int size = 32;
  *entries = 0;
  *names = reinterpret_cast<char**>(malloc(size * sizeof(char*)));

  char path[FILENAME_MAX];

  // We're allowed to delete unopened regular files in any of these
  // directories.
  const char* dirs[2] = {"/cache", "/cache/recovery/otatest"};

  for (size_t i = 0; i < sizeof(dirs)/sizeof(dirs[0]); ++i) {
    d = opendir(dirs[i]);
    if (d == NULL) {
      printf("error opening %s: %s\n", dirs[i], strerror(errno));
      continue;
    }

    // Look for regular files in the directory (not in any subdirectories).
    while ((de = readdir(d)) != 0) {
      strcpy(path, dirs[i]);
      strcat(path, "/");
      strcat(path, de->d_name);

      // We can't delete CACHE_TEMP_SOURCE; if it's there we might have
      // restarted during installation and could be depending on it to
      // be there.
      if (strcmp(path, CACHE_TEMP_SOURCE) == 0) continue;

      struct stat st;
      if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
        if (*entries >= size) {
          size *= 2;
          *names = reinterpret_cast<char**>(realloc(*names, size * sizeof(char*)));
        }
        (*names)[(*entries)++] = strdup(path);
      }
    }

    closedir(d);
  }

  printf("%d regular files in deletable directories\n", *entries);

  if (EliminateOpenFiles(*names, *entries) < 0) {
    return -1;
  }

  return 0;
}

int MakeFreeSpaceOnCache(size_t bytes_needed) {
  size_t free_now = FreeSpaceForFile("/cache");
  printf("%zu bytes free on /cache (%zu needed)\n", free_now, bytes_needed);

  if (free_now >= bytes_needed) {
    return 0;
  }

  char** names;
  int entries;

  if (FindExpendableFiles(&names, &entries) < 0) {
    return -1;
  }

  if (entries == 0) {
    // nothing we can delete to free up space!
    printf("no files can be deleted to free space on /cache\n");
    return -1;
  }

  // We could try to be smarter about which files to delete:  the
  // biggest ones?  the smallest ones that will free up enough space?
  // the oldest?  the newest?
  //
  // Instead, we'll be dumb.

  int i;
  for (i = 0; i < entries && free_now < bytes_needed; ++i) {
    if (names[i]) {
      unlink(names[i]);
      free_now = FreeSpaceForFile("/cache");
      printf("deleted %s; now %zu bytes free\n", names[i], free_now);
      free(names[i]);
    }
  }

  for (; i < entries; ++i) {
    free(names[i]);
  }
  free(names);

  return (free_now >= bytes_needed) ? 0 : -1;
}
