// Copyright 2016 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 "cobalt/speech/url_fetcher_fake.h"

#if defined(ENABLE_FAKE_MICROPHONE)

#include "base/basictypes.h"
#include "base/sys_byteorder.h"
#include "cobalt/speech/google_streaming_api.pb.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "starboard/log.h"

namespace cobalt {
namespace speech {
namespace {
const int kDownloadTimerInterval = 100;

struct RecognitionAlternative {
  const char* transcript;
  float confidence;
};

const RecognitionAlternative kAlternatives_1[] = {
    {"tube", 0.0f},
};

const RecognitionAlternative kAlternatives_2[] = {
    {"to be", 0.0f},
};

const RecognitionAlternative kAlternatives_3[] = {
    {" or not", 0.0f},
};

const RecognitionAlternative kAlternatives_4[] = {
    {" or not to be", 0.0f}, {"to be", 0.0f},
};

const RecognitionAlternative kAlternatives_5[] = {
    {"to be or not to be", 0.728f}, {"2 B or not to be", 0.0f},
};

const RecognitionAlternative kAlternatives_6[] = {
    {"that", 0.0f}, {"is the", 0.0f},
};

const RecognitionAlternative kAlternatives_7[] = {
    {"that", 0.0f}, {"is the question", 0.0f},
};

const RecognitionAlternative kAlternatives_8[] = {
    {"that is", 0.0f}, {"the question", 0.0f},
};

const RecognitionAlternative kAlternatives_9[] = {
    {"that is the question", 0.8577f}, {"that is a question", 0.0f},
};

struct RecognitionResult {
  const RecognitionAlternative* alternatives;
  bool final;
  size_t number_of_alternatives;
};

const RecognitionResult kRecognitionResults[] = {
    {kAlternatives_1, false, SB_ARRAY_SIZE_INT(kAlternatives_1)},
    {kAlternatives_2, false, SB_ARRAY_SIZE_INT(kAlternatives_2)},
    {kAlternatives_3, false, SB_ARRAY_SIZE_INT(kAlternatives_3)},
    {kAlternatives_4, false, SB_ARRAY_SIZE_INT(kAlternatives_4)},
    {kAlternatives_5, true, SB_ARRAY_SIZE_INT(kAlternatives_5)},
    {kAlternatives_6, false, SB_ARRAY_SIZE_INT(kAlternatives_6)},
    {kAlternatives_7, false, SB_ARRAY_SIZE_INT(kAlternatives_7)},
    {kAlternatives_8, false, SB_ARRAY_SIZE_INT(kAlternatives_8)},
    {kAlternatives_9, true, SB_ARRAY_SIZE_INT(kAlternatives_9)},
};

std::string GetMockProtoResult(int index) {
  proto::SpeechRecognitionEvent proto_event;
  proto_event.set_status(proto::SpeechRecognitionEvent::STATUS_SUCCESS);
  proto::SpeechRecognitionResult* proto_result = proto_event.add_result();
  proto_result->set_final(kRecognitionResults[index].final);
  const RecognitionAlternative* recognition_alternatives =
      kRecognitionResults[index].alternatives;

  for (size_t i = 0; i < kRecognitionResults[index].number_of_alternatives;
       ++i) {
    proto::SpeechRecognitionAlternative* proto_alternative =
        proto_result->add_alternative();
    proto_alternative->set_confidence(recognition_alternatives[i].confidence);
    proto_alternative->set_transcript(recognition_alternatives[i].transcript);
  }

  std::string response_string;
  proto_event.SerializeToString(&response_string);

  // Prepend 4 byte prefix length indication to the protobuf message as
  // envisaged by the google streaming recognition webservice protocol.
  uint32_t prefix =
      base::HostToNet32(static_cast<uint32_t>(response_string.size()));
  response_string.insert(0, reinterpret_cast<char*>(&prefix), sizeof(prefix));
  return response_string;
}

}  // namespace

URLFetcherFake::URLFetcherFake(const GURL& url,
                               net::URLFetcher::RequestType /*request_type*/,
                               net::URLFetcherDelegate* delegate)
    : original_url_(url),
      delegate_(delegate),
      is_chunked_upload_(false),
      download_index_(0) {}

URLFetcherFake::~URLFetcherFake() {}

void URLFetcherFake::SetChunkedUpload(
    const std::string& /*upload_content_type*/) {
  is_chunked_upload_ = true;
}

void URLFetcherFake::AppendChunkToUpload(const std::string& /*data*/,
                                         bool /*is_last_chunk*/) {
  SB_DCHECK(is_chunked_upload_);
  // no-op.
}

void URLFetcherFake::SetRequestContext(
    net::URLRequestContextGetter* /*request_context_getter*/) {
  // no-op.
}

void URLFetcherFake::Start() {
  if (!is_chunked_upload_) {
    download_timer_.emplace();
    download_timer_->Start(
        FROM_HERE, base::TimeDelta::FromMilliseconds(kDownloadTimerInterval),
        this, &URLFetcherFake::OnURLFetchDownloadData);
  }
}

const net::URLRequestStatus& URLFetcherFake::GetStatus() const {
  return fake_status_;
}

int URLFetcherFake::GetResponseCode() const { return 200; }

void URLFetcherFake::OnURLFetchDownloadData() {
  SB_DCHECK(!is_chunked_upload_);
  std::string result = GetMockProtoResult(download_index_);
  delegate_->OnURLFetchDownloadData(
      this, make_scoped_ptr<std::string>(new std::string(result)));
  download_index_++;
  if (download_index_ ==
      static_cast<int>(SB_ARRAY_SIZE_INT(kRecognitionResults))) {
    download_index_ = 0;
    download_timer_->Stop();
  }
}

}  // namespace speech
}  // namespace cobalt

#endif  // defined(ENABLE_FAKE_MICROPHONE)
