// Copyright 2016 Google Inc. 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)
