// Copyright (c) 2017 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.

#import "ios/web/net/cookies/wk_http_system_cookie_store.h"

#include "base/bind.h"
#import "base/ios/block_types.h"
#include "base/task/post_task.h"
#import "ios/net/cookies/cookie_creation_time_manager.h"
#include "ios/net/cookies/system_cookie_util.h"
#include "ios/web/public/thread/web_task_traits.h"
#include "ios/web/public/thread/web_thread.h"
#import "ios/web/web_state/ui/wk_web_view_configuration_provider.h"
#import "net/base/mac/url_conversions.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_constants.h"
#include "url/gurl.h"

#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif

namespace web {
namespace {

// Posts a task to run |block| on IO Thread. This is needed because
// WKHTTPCookieStore executes callbacks on the main thread, while
// SystemCookieStore should operate on IO thread.
void RunBlockOnIOThread(ProceduralBlock block) {
  DCHECK(block != nil);
  base::PostTask(FROM_HERE, {web::WebThread::IO}, base::BindOnce(block));
}

// Returns wether |cookie| should be included for queries about |url|.
// To include |cookie| for |url|, all these conditions need to be met:
//   1- If the cookie is secure the URL needs to be secure.
//   2- |url| domain need to match the cookie domain.
//   3- |cookie| url path need to be on the path of the given |url|.
bool ShouldIncludeForRequestUrl(NSHTTPCookie* cookie, const GURL& url) {
  // CanonicalCookies already implements cookie selection for URLs, so instead
  // of rewriting the checks here, the function converts the NSHTTPCookie to
  // canonical cookie and provide it with dummy CookieOption, so when iOS starts
  // to support cookieOptions this function can be modified to support that.
  std::unique_ptr<net::CanonicalCookie> canonical_cookie =
      net::CanonicalCookieFromSystemCookie(cookie, base::Time());
  if (!canonical_cookie)
    return false;
  // Cookies handled by this method are app specific cookies, so it's safe to
  // use strict same site context.
  net::CookieOptions options = net::CookieOptions::MakeAllInclusive();
  net::CookieAccessSemantics cookie_access_semantics =
      net::CookieAccessSemantics::LEGACY;
  if (@available(iOS 13, *)) {
    // Using |UNKNOWN| semantics to allow the experiment to switch between non
    // legacy (where cookies that don't have a specific same-site access policy
    // and not secure will not be included), and legacy mode.
    cookie_access_semantics = net::CookieAccessSemantics::UNKNOWN;
  }
  // No extra trustworthy URLs.
  bool delegate_treats_url_as_trustworthy = false;
  net::CookieAccessParams params = {
      cookie_access_semantics, delegate_treats_url_as_trustworthy,
      net::CookieSamePartyStatus::kNoSamePartyEnforcement};
  return canonical_cookie->IncludeForRequestURL(url, options, params)
      .status.IsInclude();
}

}  // namespace

WKHTTPSystemCookieStore::WKHTTPSystemCookieStore(
    WKWebViewConfigurationProvider* config_provider)
    : crw_cookie_store_([[CRWWKHTTPCookieStore alloc] init]) {
  crw_cookie_store_.HTTPCookieStore = config_provider->GetWebViewConfiguration()
                                          .websiteDataStore.httpCookieStore;
  config_provider->AddObserver(this);
}

WKHTTPSystemCookieStore::~WKHTTPSystemCookieStore() = default;

#pragma mark -
#pragma mark SystemCookieStore methods

void WKHTTPSystemCookieStore::GetCookiesForURLAsync(
    const GURL& url,
    SystemCookieCallbackForCookies callback) {
  net::ReportGetCookiesForURLCall(
      net::SystemCookieStoreType::kWKHTTPSystemCookieStore);
  GetCookiesAsyncInternal(url, std::move(callback));
}

void WKHTTPSystemCookieStore::GetAllCookiesAsync(
    SystemCookieCallbackForCookies callback) {
  GetCookiesAsyncInternal(GURL::EmptyGURL(), std::move(callback));
}

void WKHTTPSystemCookieStore::DeleteCookieAsync(NSHTTPCookie* cookie,
                                                SystemCookieCallback callback) {
  __block SystemCookieCallback shared_callback = std::move(callback);
  base::WeakPtr<net::CookieCreationTimeManager> weak_time_manager =
      creation_time_manager_->GetWeakPtr();
  NSHTTPCookie* block_cookie = cookie;
  __weak __typeof(crw_cookie_store_) block_cookie_store = crw_cookie_store_;
  base::PostTask(
      FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{
        [block_cookie_store
                 deleteCookie:block_cookie
            completionHandler:^{
              RunBlockOnIOThread(^{
                if (weak_time_manager)
                  weak_time_manager->DeleteCreationTime(block_cookie);
                if (!shared_callback.is_null())
                  std::move(shared_callback).Run();
              });
            }];
      }));
}

void WKHTTPSystemCookieStore::SetCookieAsync(
    NSHTTPCookie* cookie,
    const base::Time* optional_creation_time,
    SystemCookieCallback callback) {
  // cookies can't be set if crw_cookie_store_ is deleted.
  DCHECK(crw_cookie_store_);
  __block SystemCookieCallback shared_callback = std::move(callback);
  base::WeakPtr<net::CookieCreationTimeManager> weak_time_manager =
      creation_time_manager_->GetWeakPtr();
  NSHTTPCookie* block_cookie = cookie;
  base::Time cookie_time = base::Time::Now();
  if (optional_creation_time && !optional_creation_time->is_null())
    cookie_time = *optional_creation_time;
  __weak __typeof(crw_cookie_store_) block_cookie_store = crw_cookie_store_;
  base::PostTask(
      FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{
        [block_cookie_store
                    setCookie:block_cookie
            completionHandler:^{
              RunBlockOnIOThread(^{
                if (weak_time_manager) {
                  weak_time_manager->SetCreationTime(
                      block_cookie,
                      weak_time_manager->MakeUniqueCreationTime(cookie_time));
                }
                if (!shared_callback.is_null())
                  std::move(shared_callback).Run();
              });
            }];
      }));
}

void WKHTTPSystemCookieStore::ClearStoreAsync(SystemCookieCallback callback) {
  __block SystemCookieCallback shared_callback = std::move(callback);
  base::WeakPtr<net::CookieCreationTimeManager> weak_time_manager =
      creation_time_manager_->GetWeakPtr();
  __weak __typeof(crw_cookie_store_) block_cookie_store = crw_cookie_store_;
  base::PostTask(
      FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{
        [block_cookie_store getAllCookies:^(NSArray<NSHTTPCookie*>* cookies) {
          ProceduralBlock completionHandler = ^{
            RunBlockOnIOThread(^{
              if (weak_time_manager)
                weak_time_manager->Clear();
              std::move(shared_callback).Run();
            });
          };

          // If there are no cookies to clear, immediately invoke the
          // completion handler on IO thread, otherwise count the number
          // of cookies that still need to be cleared and invoke it when
          // all of them have been cleared.
          __block NSUInteger remainingCookiesToClearCount = cookies.count;
          if (remainingCookiesToClearCount == 0) {
            completionHandler();
            return;
          }

          for (NSHTTPCookie* cookie in cookies) {
            [block_cookie_store deleteCookie:cookie
                           completionHandler:^{
                             DCHECK(remainingCookiesToClearCount);
                             if (--remainingCookiesToClearCount == 0) {
                               completionHandler();
                             }
                           }];
          }
        }];
      }));
}

NSHTTPCookieAcceptPolicy WKHTTPSystemCookieStore::GetCookieAcceptPolicy() {
  // TODO(crbug.com/759226): Make sure there is no other way to return
  // WKHTTPCookieStore Specific cookieAcceptPolicy.
  return [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookieAcceptPolicy];
}

#pragma mark WKWebViewConfigurationProviderObserver implementation

void WKHTTPSystemCookieStore::DidCreateNewConfiguration(
    WKWebViewConfigurationProvider* provider,
    WKWebViewConfiguration* new_config) {
  crw_cookie_store_.HTTPCookieStore =
      new_config.websiteDataStore.httpCookieStore;
}

#pragma mark private methods

void WKHTTPSystemCookieStore::GetCookiesAsyncInternal(
    const GURL& include_url,
    SystemCookieCallbackForCookies callback) {
  __block SystemCookieCallbackForCookies shared_callback = std::move(callback);
  base::WeakPtr<net::CookieCreationTimeManager> weak_time_manager =
      creation_time_manager_->GetWeakPtr();
  __weak __typeof(crw_cookie_store_) weak_cookie_store = crw_cookie_store_;
  GURL block_url = include_url;
  base::PostTask(
      FROM_HERE, {web::WebThread::UI}, base::BindOnce(^{
        __typeof(weak_cookie_store) strong_cookie_store = weak_cookie_store;
        if (strong_cookie_store) {
          [strong_cookie_store
              getAllCookies:^(NSArray<NSHTTPCookie*>* cookies) {
                ProcessGetCookiesResultInIOThread(std::move(shared_callback),
                                                  weak_time_manager, block_url,
                                                  cookies);
              }];
        } else {
          ProcessGetCookiesResultInIOThread(std::move(shared_callback),
                                            weak_time_manager, block_url, @[]);
        }
      }));
}

// static
void WKHTTPSystemCookieStore::ProcessGetCookiesResultInIOThread(
    net::SystemCookieStore::SystemCookieCallbackForCookies callback,
    base::WeakPtr<net::CookieCreationTimeManager> weak_time_manager,
    const GURL& include_url,
    NSArray<NSHTTPCookie*>* _Nonnull cookies) {
  if (callback.is_null())
    return;
  __block NSArray* block_cookies = cookies;
  GURL block_url = include_url;

  __block net::SystemCookieStore::SystemCookieCallbackForCookies
      shared_callback = std::move(callback);
  RunBlockOnIOThread(^{
    if (!block_url.is_empty()) {
      NSMutableArray* filtered_cookies = [NSMutableArray array];
      for (NSHTTPCookie* cookie in block_cookies) {
        if (ShouldIncludeForRequestUrl(cookie, block_url)) {
          [filtered_cookies addObject:cookie];
        }
      }
      net::ReportGetCookiesForURLResult(
          net::SystemCookieStoreType::kWKHTTPSystemCookieStore,
          filtered_cookies.count != 0);
      block_cookies = filtered_cookies;
    }

    if (weak_time_manager) {
      NSArray* sorted_results = [block_cookies
          sortedArrayUsingFunction:net::SystemCookieStore::CompareCookies
                           context:weak_time_manager.get()];
      std::move(shared_callback).Run(sorted_results);
    } else {
      std::move(shared_callback).Run([block_cookies copy]);
    }
  });
}

}  // namespace web
