// Copyright 2013 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/browser/media_galleries/fileapi/supported_audio_video_checker.h"

#include <stddef.h>
#include <set>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/callback.h"
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/stl_util.h"
#include "base/task_scheduler/post_task.h"
#include "base/task_scheduler/task_traits.h"
#include "base/threading/thread_restrictions.h"
#include "chrome/browser/media_galleries/fileapi/safe_audio_video_checker.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/mime_util.h"
#include "third_party/WebKit/common/mime_util/mime_util.h"

namespace {

class SupportedAudioVideoExtensions {
 public:
  SupportedAudioVideoExtensions() {
    std::vector<base::FilePath::StringType> extensions;
    net::GetExtensionsForMimeType("audio/*", &extensions);
    net::GetExtensionsForMimeType("video/*", &extensions);
    for (size_t i = 0; i < extensions.size(); ++i) {
      std::string mime_type;
      if (net::GetWellKnownMimeTypeFromExtension(extensions[i], &mime_type) &&
          blink::IsSupportedMimeType(mime_type)) {
        audio_video_extensions_.insert(
            base::FilePath::kExtensionSeparator + extensions[i]);
      }
    }
  }

  bool HasSupportedAudioVideoExtension(const base::FilePath& file) {
    return base::ContainsKey(audio_video_extensions_, file.Extension());
  }

 private:
  std::set<base::FilePath::StringType> audio_video_extensions_;

  DISALLOW_COPY_AND_ASSIGN(SupportedAudioVideoExtensions);
};

base::LazyInstance<SupportedAudioVideoExtensions>::DestructorAtExit
    g_audio_video_extensions = LAZY_INSTANCE_INITIALIZER;

base::File OpenBlocking(const base::FilePath& path) {
  base::ThreadRestrictions::AssertIOAllowed();
  return base::File(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
}

}  // namespace

SupportedAudioVideoChecker::~SupportedAudioVideoChecker() {}

// static
bool SupportedAudioVideoChecker::SupportsFileType(const base::FilePath& path) {
  return g_audio_video_extensions.Get().HasSupportedAudioVideoExtension(path);
}

void SupportedAudioVideoChecker::StartPreWriteValidation(
    const storage::CopyOrMoveFileValidator::ResultCallback& result_callback) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
  DCHECK(callback_.is_null());
  callback_ = result_callback;

  base::PostTaskWithTraitsAndReplyWithResult(
      FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
      base::BindOnce(&OpenBlocking, path_),
      base::BindOnce(&SupportedAudioVideoChecker::OnFileOpen,
                     weak_factory_.GetWeakPtr()));
}

SupportedAudioVideoChecker::SupportedAudioVideoChecker(
    const base::FilePath& path)
    : path_(path),
      weak_factory_(this) {
}

void SupportedAudioVideoChecker::OnFileOpen(base::File file) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
  if (!file.IsValid()) {
    callback_.Run(base::File::FILE_ERROR_SECURITY);
    return;
  }

  safe_checker_ = new SafeAudioVideoChecker(std::move(file), callback_);
  safe_checker_->Start();
}
