// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// 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 <memory>

#include "cobalt/loader/sync_loader.h"

#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/synchronization/waitable_event.h"
#include "base/trace_event/trace_event.h"

namespace cobalt {
namespace loader {
namespace {

//////////////////////////////////////////////////////////////////
// Helpers
//////////////////////////////////////////////////////////////////

class FetcherToDecoderAdapter;

// This class is responsible for loading resource using the given fetcher and
// decoder creators.
class LoaderOnThread {
 public:
  LoaderOnThread(base::Callback<void(const base::Optional<std::string>&)>
                     load_complete_callback)
      : load_complete_callback_(load_complete_callback),
        load_complete_waitable_event_(
            base::WaitableEvent::ResetPolicy::MANUAL,
            base::WaitableEvent::InitialState::NOT_SIGNALED),
        end_waitable_event_(base::WaitableEvent::ResetPolicy::MANUAL,
                            base::WaitableEvent::InitialState::NOT_SIGNALED) {}

  // Start() and End() should be called on the same thread, the sychronous load
  // thread, so the member objects are created, execute, and are destroyed,
  // on that same thread.
  void Start(base::Callback<std::unique_ptr<Fetcher>(Fetcher::Handler*)>
                 fetcher_creator,
             base::Callback<std::unique_ptr<Decoder>()> decoder_creator);
  void End();

  void SignalLoadComplete(const base::Optional<std::string>& error) {
    load_complete_callback_.Run(error);
    load_complete_waitable_event_.Signal();
  }
  void SignalEndDone() { end_waitable_event_.Signal(); }

  // Returns true if start completed normally, returns false if the wait was
  // interrupted by |interrupt_event|.
  void WaitForLoad(base::WaitableEvent* interrupt_event) {
    base::WaitableEvent* event_array[] = {&load_complete_waitable_event_,
                                          interrupt_event};
    size_t effective_size = arraysize(event_array);
    if (!interrupt_event) {
      --effective_size;
    }
    base::WaitableEvent::WaitMany(event_array, effective_size);
  }

  void WaitForEnd() { end_waitable_event_.Wait(); }

 private:
  base::Callback<void(const base::Optional<std::string>&)>
      load_complete_callback_;

  std::unique_ptr<Decoder> decoder_;
  std::unique_ptr<FetcherToDecoderAdapter> fetcher_to_decoder_adaptor_;
  std::unique_ptr<Fetcher> fetcher_;

  base::WaitableEvent load_complete_waitable_event_;
  base::WaitableEvent end_waitable_event_;
};

// This class is responsible for passing chunks of data from fetcher to decoder
// and notifying fetching is done or aborted on error.
class FetcherToDecoderAdapter : public Fetcher::Handler {
 public:
  FetcherToDecoderAdapter(
      LoaderOnThread* loader_on_thread, Decoder* decoder,
      base::Callback<void(const base::Optional<std::string>&)>
          load_complete_callback)
      : loader_on_thread_(loader_on_thread), decoder_(decoder) {}

  // From Fetcher::Handler.
  void OnReceived(Fetcher* fetcher, const char* data, size_t size) override {
    SB_UNREFERENCED_PARAMETER(fetcher);
    decoder_->DecodeChunk(data, size);
  }
  void OnDone(Fetcher* fetcher) override {
    DCHECK(fetcher);
    decoder_->SetLastURLOrigin(fetcher->last_url_origin());
    decoder_->Finish();
    loader_on_thread_->SignalLoadComplete(base::nullopt);
  }
  void OnError(Fetcher* /*fetcher*/, const std::string& error) override {
    loader_on_thread_->SignalLoadComplete(error);
  }

 private:
  LoaderOnThread* loader_on_thread_;
  Decoder* decoder_;
};

void LoaderOnThread::Start(
    base::Callback<std::unique_ptr<Fetcher>(Fetcher::Handler*)> fetcher_creator,
    base::Callback<std::unique_ptr<Decoder>()> decoder_creator) {
  decoder_ = decoder_creator.Run();
  fetcher_to_decoder_adaptor_.reset(new FetcherToDecoderAdapter(
      this, decoder_.get(), load_complete_callback_));
  fetcher_ = fetcher_creator.Run(fetcher_to_decoder_adaptor_.get());
}

void LoaderOnThread::End() {
  fetcher_.reset();
  fetcher_to_decoder_adaptor_.reset();
  decoder_.reset();

  if (!load_complete_waitable_event_.IsSignaled()) {
    // We were interrupted, and we did not complete.  Call the
    // |load_complete_callback| "manually" to indicate this.
    load_complete_callback_.Run(
        "Synchronous load was interrupted (probably due to the process "
        "suspending).  This probably implies that there is a suspend/resume "
        "bug (are you using inlined <script> tags?  If so, switch to loading "
        "scripts via JavaScript e.g. by using "
        "document.createElement('script')).");
  }

  SignalEndDone();
}

}  // namespace

//////////////////////////////////////////////////////////////////
// LoadSynchronously
//////////////////////////////////////////////////////////////////

void LoadSynchronously(
    base::MessageLoop* message_loop, base::WaitableEvent* interrupt_trigger,
    base::Callback<std::unique_ptr<Fetcher>(Fetcher::Handler*)> fetcher_creator,
    base::Callback<std::unique_ptr<Decoder>()> decoder_creator,
    base::Callback<void(const base::Optional<std::string>&)>
        load_complete_callback) {
  TRACE_EVENT0("cobalt::loader", "LoadSynchronously()");
  DCHECK(message_loop);
  DCHECK(!load_complete_callback.is_null());

  LoaderOnThread loader_on_thread(load_complete_callback);

  message_loop->task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&LoaderOnThread::Start, base::Unretained(&loader_on_thread),
                 fetcher_creator, decoder_creator));
  loader_on_thread.WaitForLoad(interrupt_trigger);

  message_loop->task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&LoaderOnThread::End, base::Unretained(&loader_on_thread)));

  // Wait for a different event here, since it is possible that the first
  // wait was interrupted, and the fetcher completion can still |Signal()|
  // the start event.
  loader_on_thread.WaitForEnd();
}

}  // namespace loader
}  // namespace cobalt
