// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/installer/util/self_cleaning_temp_dir.h"

#include <windows.h>

#include "base/file_util.h"
#include "base/logging.h"
#include "chrome/installer/util/delete_after_reboot_helper.h"

namespace installer {

// Populates |base_dir| with the topmost directory in the hierarchy of
// |temp_parent_dir| that does not exist.  If |temp_parent_dir| exists,
// |base_dir| is cleared.
// static
void SelfCleaningTempDir::GetTopDirToCreate(
    const base::FilePath& temp_parent_dir,
    base::FilePath* base_dir) {
  DCHECK(base_dir);

  if (base::PathExists(temp_parent_dir)) {
    // Empty base_dir means that we didn't create any extra directories.
    base_dir->clear();
  } else {
    base::FilePath parent_dir(temp_parent_dir);
    do {
      *base_dir = parent_dir;
      parent_dir = parent_dir.DirName();
    } while (parent_dir != *base_dir && !base::PathExists(parent_dir));
    LOG_IF(WARNING, !base::DirectoryExists(parent_dir))
        << "A non-directory is at the base of the path leading to a desired "
           "temp directory location: " << parent_dir.value();
  }
}

SelfCleaningTempDir::SelfCleaningTempDir() {
}

SelfCleaningTempDir::~SelfCleaningTempDir() {
  if (!path().empty() && !Delete())
    LOG(WARNING) << "Failed to clean temp dir in dtor " << path().value();
}

bool SelfCleaningTempDir::Initialize(const base::FilePath& parent_dir,
                                     const StringType& temp_name) {
  DCHECK(parent_dir.IsAbsolute());
  DCHECK(!temp_name.empty());

  if (!path().empty()) {
    LOG(DFATAL) << "Attempting to re-initialize a SelfSelfCleaningTempDir.";
    return false;
  }

  base::FilePath temp_dir(parent_dir.Append(temp_name));
  base::FilePath base_dir;
  GetTopDirToCreate(parent_dir, &base_dir);

  if (file_util::CreateDirectory(temp_dir)) {
    base_dir_ = base_dir;
    temp_dir_ = temp_dir;
    return true;
  }

  return false;
}

bool SelfCleaningTempDir::Delete() {
  if (path().empty()) {
    LOG(DFATAL) << "Attempting to Delete an uninitialized SelfCleaningTempDir.";
    return false;
  }

  base::FilePath next_dir(path().DirName());
  bool schedule_deletes = false;

  // First try to recursively delete the leaf directory managed by our
  // base::ScopedTempDir.
  if (!base::DeleteFile(path(), true)) {
    // That failed, so schedule the temp dir and its contents for deletion after
    // reboot.
    LOG(WARNING) << "Failed to delete temporary directory " << path().value()
                 << ". Scheduling for deletion at reboot.";
    schedule_deletes = true;
    if (!ScheduleDirectoryForDeletion(path()))
      return false;  // Entirely unexpected failure (Schedule logs the reason).
  }

  // Now delete or schedule all empty directories up to and including our
  // base_dir_.  Any that can't be deleted are scheduled for deletion at reboot.
  // This is safe since they'll only be deleted in that case if they're empty.
  if (!base_dir_.empty()) {
    do {
      if (!schedule_deletes && !RemoveDirectory(next_dir.value().c_str())) {
        PLOG_IF(WARNING, GetLastError() != ERROR_DIR_NOT_EMPTY)
              << "Error removing directory " << next_dir.value().c_str();
        schedule_deletes = true;
      }
      if (schedule_deletes) {
        // Ignore the return code.  If we fail to schedule, go ahead and add the
        // other parent directories anyway.
        ScheduleFileSystemEntityForDeletion(next_dir);
      }
      if (next_dir == base_dir_)
        break;  // We just processed the topmost directory we created.
      next_dir = next_dir.DirName();
    } while (true);
  }

  base_dir_.clear();
  temp_dir_.clear();

  return true;
}

}  // namespace installer
