// 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_frame/urlmon_bind_status_callback.h"

#include <mshtml.h>
#include <shlguid.h>

#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/platform_thread.h"
#include "chrome_frame/bind_context_info.h"
#include "chrome_frame/chrome_tab.h"
#include "chrome_frame/exception_barrier.h"
#include "chrome_frame/urlmon_moniker.h"


// A helper to given feed data to the specified |bscb| using
// CacheStream instance.
HRESULT CacheStream::BSCBFeedData(IBindStatusCallback* bscb, const char* data,
                                  size_t size, CLIPFORMAT clip_format,
                                  size_t flags, bool eof) {
  if (!bscb) {
    NOTREACHED() << "invalid IBindStatusCallback";
    return E_INVALIDARG;
  }

  // We can't use a CComObjectStackEx here since mshtml will hold
  // onto the stream pointer.
  CComObject<CacheStream>* cache_stream = NULL;
  HRESULT hr = CComObject<CacheStream>::CreateInstance(&cache_stream);
  if (FAILED(hr)) {
    NOTREACHED();
    return hr;
  }

  scoped_refptr<CacheStream> cache_ref = cache_stream;
  hr = cache_stream->Initialize(data, size, eof);
  if (FAILED(hr))
    return hr;

  FORMATETC format_etc = { clip_format, NULL, DVASPECT_CONTENT, -1,
                           TYMED_ISTREAM };
  STGMEDIUM medium = {0};
  medium.tymed = TYMED_ISTREAM;
  medium.pstm = cache_stream;

  hr = bscb->OnDataAvailable(flags, size, &format_etc, &medium);
  return hr;
}

HRESULT CacheStream::Initialize(const char* cache, size_t size, bool eof) {
  position_ = 0;
  eof_ = eof;

  HRESULT hr = S_OK;
  cache_.reset(new char[size]);
  if (cache_.get()) {
    memcpy(cache_.get(), cache, size);
    size_ = size;
  } else {
    DLOG(ERROR) << "failed to allocate cache stream.";
    hr = E_OUTOFMEMORY;
  }

  return hr;
}

// Read is the only call that we expect. Return E_PENDING if there
// is no more data to serve. Otherwise this will result in a
// read with 0 bytes indicating that no more data is available.
STDMETHODIMP CacheStream::Read(void* pv, ULONG cb, ULONG* read) {
  if (!pv || !read)
    return E_INVALIDARG;

  if (!cache_.get()) {
    *read = 0;
    return S_FALSE;
  }

  // Default to E_PENDING to signal that this is a partial data.
  HRESULT hr = eof_ ? S_FALSE : E_PENDING;
  if (position_ < size_) {
    *read = std::min(size_ - position_, size_t(cb));
    memcpy(pv, cache_ .get() + position_, *read);
    position_ += *read;
    hr = S_OK;
  }

  return hr;
}


/////////////////////////////////////////////////////////////////////

HRESULT SniffData::InitializeCache(const std::wstring& url) {
  url_ = url;
  renderer_type_ = UNDETERMINED;

  const int kInitialSize = 4 * 1024; // 4K
  HGLOBAL mem = GlobalAlloc(0, kInitialSize);
  DCHECK(mem) << "GlobalAlloc failed: " << GetLastError();

  HRESULT hr = CreateStreamOnHGlobal(mem, TRUE, cache_.Receive());
  if (SUCCEEDED(hr)) {
    ULARGE_INTEGER size = {0};
    cache_->SetSize(size);
  } else {
    DLOG(ERROR) << "CreateStreamOnHGlobal failed: " << hr;
  }

  return hr;
}

HRESULT SniffData::ReadIntoCache(IStream* stream, bool force_determination) {
  if (!stream) {
    NOTREACHED();
    return E_INVALIDARG;
  }

  HRESULT hr = S_OK;
  while (SUCCEEDED(hr)) {
    const size_t kChunkSize = 4 * 1024;
    char buffer[kChunkSize];
    DWORD read = 0;
    hr = stream->Read(buffer, sizeof(buffer), &read);
    if (read) {
      DWORD written = 0;
      cache_->Write(buffer, read, &written);
      size_ += written;
    }

    if ((S_FALSE == hr) || !read)
      break;
  }

  bool last_chance = force_determination || (size() >= kMaxSniffSize);
  eof_ = force_determination;
  DetermineRendererType(last_chance);
  return hr;
}

HRESULT SniffData::DrainCache(IBindStatusCallback* bscb, DWORD bscf,
                              CLIPFORMAT clip_format) {
  if (!is_cache_valid()) {
    return S_OK;
  }

  // Ideally we could just use the cache_ IStream implementation but
  // can't use it here since we have to return E_PENDING for the
  // last call
  HGLOBAL memory = NULL;
  HRESULT hr = GetHGlobalFromStream(cache_, &memory);
  if (SUCCEEDED(hr) && memory) {
    char* buffer = reinterpret_cast<char*>(GlobalLock(memory));
    hr = CacheStream::BSCBFeedData(bscb, buffer, size_, clip_format, bscf,
                                   eof_);
    GlobalUnlock(memory);
  }

  size_ = 0;
  cache_.Release();
  return hr;
}

// Scan the buffer or OptIn URL list and decide if the renderer is
// to be switched.  Last chance means there's no more data.
void SniffData::DetermineRendererType(bool last_chance) {
  if (is_undetermined()) {
    if (last_chance)
      renderer_type_ = OTHER;
    if (IsChrome(RendererTypeForUrl(url_))) {
      renderer_type_ = CHROME;
    } else {
      if (is_cache_valid() && cache_) {
        HGLOBAL memory = NULL;
        GetHGlobalFromStream(cache_, &memory);
        const char* buffer = reinterpret_cast<const char*>(GlobalLock(memory));

        std::wstring html_contents;
        // TODO(joshia): detect and handle different content encodings
        if (buffer && size_) {
          UTF8ToWide(buffer, std::min(size_, kMaxSniffSize), &html_contents);
          GlobalUnlock(memory);
        }

        // Note that document_contents_ may have NULL characters in it. While
        // browsers may handle this properly, we don't and will stop scanning
        // for the XUACompat content value if we encounter one.
        std::wstring xua_compat_content;
        UtilGetXUACompatContentValue(html_contents, &xua_compat_content);
        if (StrStrI(xua_compat_content.c_str(), kChromeContentPrefix)) {
          renderer_type_ = CHROME;
        }
      }
    }
    DVLOG(1) << __FUNCTION__ << "Url: " << url_ << base::StringPrintf(
          "Renderer type: %s", renderer_type_ == CHROME ? "CHROME" : "OTHER");
  }
}

/////////////////////////////////////////////////////////////////////

BSCBStorageBind::BSCBStorageBind() : clip_format_(CF_NULL) {
}

BSCBStorageBind::~BSCBStorageBind() {
  std::for_each(saved_progress_.begin(), saved_progress_.end(),
                utils::DeleteObject());
}

HRESULT BSCBStorageBind::Initialize(IMoniker* moniker, IBindCtx* bind_ctx) {
  DVLOG(1) << __FUNCTION__ << me()
           << base::StringPrintf(" tid=%i", base::PlatformThread::CurrentId());

  std::wstring url = GetActualUrlFromMoniker(moniker, bind_ctx,
                                             std::wstring());
  HRESULT hr = data_sniffer_.InitializeCache(url);
  if (FAILED(hr))
    return hr;

  hr = AttachToBind(bind_ctx);
  if (FAILED(hr)) {
    NOTREACHED() << __FUNCTION__ << me() << "AttachToBind error: " << hr;
    return hr;
  }

  if (!delegate()) {
    NOTREACHED() << __FUNCTION__ << me() << "No existing callback: " << hr;
    return E_FAIL;
  }

  return hr;
}

STDMETHODIMP BSCBStorageBind::OnProgress(ULONG progress, ULONG progress_max,
                                    ULONG status_code, LPCWSTR status_text) {
  DVLOG(1) << __FUNCTION__ << me()
           << base::StringPrintf(" status=%i tid=%i %ls", status_code,
                                 base::PlatformThread::CurrentId(),
                                 status_text);
  // Report all crashes in the exception handler if we wrap the callback.
  // Note that this avoids having the VEH report a crash if an SEH earlier in
  // the chain handles the exception.
  ExceptionBarrier barrier;

  HRESULT hr = S_OK;

  // TODO(ananta)
  // ChromeFrame will not be informed of any redirects which occur while we
  // switch into Chrome. This will only break the moniker patch which is
  // legacy and needs to be deleted.

  if (ShouldCacheProgress(status_code)) {
    saved_progress_.push_back(new Progress(progress, progress_max, status_code,
                                           status_text));
  } else {
    hr = CallbackImpl::OnProgress(progress, progress_max, status_code,
                               status_text);
  }

  return hr;
}

// Refer to urlmon_moniker.h for explanation of how things work.
STDMETHODIMP BSCBStorageBind::OnDataAvailable(DWORD flags, DWORD size,
                                              FORMATETC* format_etc,
                                              STGMEDIUM* stgmed) {
  DVLOG(1) << __FUNCTION__
           << base::StringPrintf(" tid=%i", base::PlatformThread::CurrentId());
  // Report all crashes in the exception handler if we wrap the callback.
  // Note that this avoids having the VEH report a crash if an SEH earlier in
  // the chain handles the exception.
  ExceptionBarrier barrier;
  // Do not touch anything other than text/html.
  bool is_interesting = (format_etc && stgmed && stgmed->pstm &&
      stgmed->tymed == TYMED_ISTREAM &&
      IsTextHtmlClipFormat(format_etc->cfFormat));

  if (!is_interesting) {
    // Play back report progress so far.
    MayPlayBack(flags);
    return CallbackImpl::OnDataAvailable(flags, size, format_etc, stgmed);
  }

  HRESULT hr = S_OK;
  if (!clip_format_)
    clip_format_ = format_etc->cfFormat;

  if (data_sniffer_.is_undetermined()) {
    bool force_determination = !!(flags &
        (BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE));
    hr = data_sniffer_.ReadIntoCache(stgmed->pstm, force_determination);
    // If we don't have sufficient data to determine renderer type
    // wait for the next data notification.
    if (data_sniffer_.is_undetermined())
      return S_OK;
  }

  DCHECK(!data_sniffer_.is_undetermined());

  if (data_sniffer_.is_cache_valid()) {
    hr = MayPlayBack(flags);
    DCHECK(!data_sniffer_.is_cache_valid());
  } else {
    hr = CallbackImpl::OnDataAvailable(flags, size, format_etc, stgmed);
  }
  return hr;
}

STDMETHODIMP BSCBStorageBind::OnStopBinding(HRESULT hresult, LPCWSTR error) {
  DVLOG(1) << __FUNCTION__
           << base::StringPrintf(" tid=%i", base::PlatformThread::CurrentId());
  // Report all crashes in the exception handler if we wrap the callback.
  // Note that this avoids having the VEH report a crash if an SEH earlier in
  // the chain handles the exception.
  ExceptionBarrier barrier;

  HRESULT hr = MayPlayBack(BSCF_LASTDATANOTIFICATION);
  hr = CallbackImpl::OnStopBinding(hresult, error);
  ReleaseBind();
  return hr;
}

// Play back the cached data to the delegate. Normally this would happen
// when we have read enough data to determine the renderer. In this case
// we first play back the data from the cache and then go into a 'pass
// through' mode.  In some cases we may end up getting OnStopBinding
// before we get a chance to determine. Also it's possible that the
// BindToStorage call will return before OnStopBinding is sent. Hence
// This is called from 3 places and it's important to maintain the
// exact sequence of calls.
// Once the data is played back, calling this again is a no op.
HRESULT BSCBStorageBind::MayPlayBack(DWORD flags) {
  // Force renderer type determination if not already done since
  // we want to play back data now.
  data_sniffer_.DetermineRendererType(true);
  DCHECK(!data_sniffer_.is_undetermined());

  HRESULT hr = S_OK;
  if (data_sniffer_.is_chrome()) {
    // Remember clip format.  If we are switching to chrome, then in order
    // to make mshtml return INET_E_TERMINATED_BIND and reissue navigation
    // with the same bind context, we have to return a mime type that is
    // special cased by mshtml.
    static const CLIPFORMAT kMagicClipFormat =
        RegisterClipboardFormat(CFSTR_MIME_MPEG);
    clip_format_ = kMagicClipFormat;
  } else {
    if (!saved_progress_.empty()) {
      for (ProgressVector::iterator i = saved_progress_.begin();
           i != saved_progress_.end(); i++) {
        Progress* p = (*i);
        // We don't really expect a race condition here but just for sake
        // of completeness we check.
        if (p) {
          (*i) = NULL;
          CallbackImpl::OnProgress(p->progress(), p->progress_max(),
                                   p->status_code(), p->status_text());
          delete p;
        }
      }
      saved_progress_.clear();
    }
  }

  if (data_sniffer_.is_cache_valid()) {
    if (data_sniffer_.is_chrome()) {
      base::win::ScopedComPtr<BindContextInfo> info;
      BindContextInfo::FromBindContext(bind_ctx_, info.Receive());
      DCHECK(info);
      if (info) {
        info->SetToSwitch(data_sniffer_.cache_);
      }
    }

    hr = data_sniffer_.DrainCache(delegate(),
        flags | BSCF_FIRSTDATANOTIFICATION, clip_format_);
    DLOG_IF(WARNING, INET_E_TERMINATED_BIND != hr) << __FUNCTION__ <<
      " mshtml OnDataAvailable returned: " << std::hex << hr;
  }

  return hr;
}

// We cache and suppress sending progress notifications till
// we get the first OnDataAvailable. This is to prevent
// mshtml from making up its mind about the mime type.
// However, this is the invasive part of the patch and
// could trip other software that's due to mistimed progress
// notifications. It is probably not a good idea to hide redirects
// and some cookie notifications.
//
// We only need to suppress data notifications like
// BINDSTATUS_MIMETYPEAVAILABLE,
// BINDSTATUS_CACHEFILENAMEAVAILABLE etc.
//
// This is an atempt to reduce the exposure by starting to
// cache only when we receive one of the interesting progress
// notification.
bool BSCBStorageBind::ShouldCacheProgress(unsigned long status_code) const {
  // We need to cache progress notifications only if we haven't yet figured
  // out which way the request is going.
  if (data_sniffer_.is_undetermined()) {
    // If we are already caching then continue.
    if (!saved_progress_.empty())
      return true;
    // Start caching only if we see one of the interesting progress
    // notifications.
    switch (status_code) {
      case BINDSTATUS_BEGINDOWNLOADDATA:
      case BINDSTATUS_DOWNLOADINGDATA:
      case BINDSTATUS_USINGCACHEDCOPY:
      case BINDSTATUS_MIMETYPEAVAILABLE:
      case BINDSTATUS_CACHEFILENAMEAVAILABLE:
      case BINDSTATUS_SERVER_MIMETYPEAVAILABLE:
        return true;
      default:
        break;
    }
  }

  return false;
}
