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

//
// Helper classes for tests including a mock Scheduler, a mock network and a
// mock storage layer.

#include <set>

#include "google/cacheinvalidation/impl/proto-converter.h"
#include "google/cacheinvalidation/test/test-utils.h"
#include "google/cacheinvalidation/test/test-logger.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"

namespace invalidation {

using ::google::protobuf::io::StringOutputStream;
using ::testing::DeleteArg;
using ::testing::StrictMock;

// Creates an Action InvokeNetworkStatusCallback<k>() that calls the Run method
// on the kth argument with value |true|.
ACTION_TEMPLATE(
    InvokeNetworkStatusCallback,
    HAS_1_TEMPLATE_PARAMS(int, k),
    AND_0_VALUE_PARAMS()) {
  std::tr1::get<k>(args)->Run(true);
}

const char* UnitTestBase::kClientToken = "Dummy";

void UnitTestBase::SetUp() {
  // Start time at an arbitrary point, just to make sure we don't depend on it
  // being 0.
  start_time = Time() + TimeDelta::FromDays(9);
  statistics.reset(new Statistics());
  reg_summary.reset(new RegistrationSummary());
  InitZeroRegistrationSummary(reg_summary.get());
  InitSystemResources();  // Set up system resources
  message_callback = NULL;

  // Start the scheduler and resources.
  internal_scheduler->StartScheduler();
  resources->Start();
}

void UnitTestBase::TearDown() {
  if (message_callback != NULL) {
    delete message_callback;
    message_callback = NULL;
  }
}

void UnitTestBase::InitSystemResources() {
  logger = new TestLogger();

  // Use a deterministic scheduler for the protocol handler's internals, since
  // we want precise control over when batching intervals expire.
  internal_scheduler = new DeterministicScheduler(logger);
  internal_scheduler->SetInitialTime(start_time);

  // Use a mock network to let us trap the protocol handler's message receiver
  // and its attempts to send messages.
  network = new StrictMock<MockNetwork>();
  listener_scheduler = new StrictMock<MockScheduler>();

  // Storage shouldn't be used by the protocol handler, so use a strict mock
  // to catch any accidental calls.
  storage = new StrictMock<MockStorage>();

  // The BasicSystemResources will set itself in the components.
  EXPECT_CALL(*network, SetSystemResources(_));
  EXPECT_CALL(*storage, SetSystemResources(_));
  EXPECT_CALL(*listener_scheduler, SetSystemResources(_));

  // Create the actual resources.
  resources.reset(new BasicSystemResources(
      logger, internal_scheduler, listener_scheduler, network, storage,
      "unit-test"));
}

void UnitTestBase::InitCommonExpectations() {
  // When we construct the protocol handler, it will set a message receiver on
  // the network. Intercept the call and save the callback.
  EXPECT_CALL(*network, SetMessageReceiver(_))
      .WillOnce(SaveArg<0>(&message_callback));

  // It will also add a network status receiver.  The network channel takes
  // ownership. Invoke it once with |true| just to exercise that code path,
  // then delete it since we won't need it anymore.
  EXPECT_CALL(*network, AddNetworkStatusReceiver(_))
      .WillOnce(DoAll(InvokeNetworkStatusCallback<0>(), DeleteArg<0>()));
}

void UnitTestBase::InitRegistrationMessage(const vector<ObjectIdP>& oids,
    bool is_reg, RegistrationMessage *reg_message) {
  RegistrationP::OpType op_type = is_reg ?
      RegistrationP::REGISTER : RegistrationP::UNREGISTER;
  for (size_t i = 0; i < oids.size(); i++) {
    ProtoHelpers::InitRegistrationP(
        oids[i], op_type, reg_message->add_registration());
  }
}

void UnitTestBase::InitErrorMessage(ErrorMessage::Code error_code,
    const string& description, ErrorMessage* error_message) {
  error_message->set_code(error_code);
  error_message->set_description(description);
}

void UnitTestBase::InitInvalidationMessage(const vector<InvalidationP>& invs,
    InvalidationMessage *inv_message) {
  for (size_t i = 0; i < invs.size(); ++i) {
    inv_message->add_invalidation()->CopyFrom(invs[i]);
  }
}

TimeDelta UnitTestBase::EndOfTestWaitTime() {
  return TimeDelta::FromSeconds(50);
}

TimeDelta UnitTestBase::MessageHandlingDelay() {
  return TimeDelta::FromMilliseconds(50);
}

void UnitTestBase::InitTestObjectIds(int count, vector<ObjectIdP>* object_ids) {
  for (int i = 0; i < count; ++i) {
    ObjectIdP object_id;
    object_id.set_source(ObjectSource_Type_TEST);
    object_id.set_name(StringPrintf("oid%d", i));
    object_ids->push_back(object_id);
  }
}

void UnitTestBase::ConvertFromObjectIdProtos(
    const vector<ObjectIdP>& oid_protos, vector<ObjectId> *oids) {
  for (size_t i = 0; i < oid_protos.size(); ++i) {
    ObjectId object_id;
    ProtoConverter::ConvertFromObjectIdProto(oid_protos[i], &object_id);
    oids->push_back(object_id);
  }
}

void UnitTestBase::ConvertFromInvalidationProtos(
      const vector<InvalidationP>& inv_protos, vector<Invalidation> *invs) {
  for (size_t i = 0; i < inv_protos.size(); ++i) {
    Invalidation inv;
    ProtoConverter::ConvertFromInvalidationProto(inv_protos[i], &inv);
    invs->push_back(inv);
  }
}

void UnitTestBase::MakeInvalidationsFromObjectIds(
    const vector<ObjectIdP>& object_ids,
    vector<InvalidationP>* invalidations) {
  for (size_t i = 0; i < object_ids.size(); ++i) {
    InvalidationP invalidation;
    invalidation.mutable_object_id()->CopyFrom(object_ids[i]);
    invalidation.set_is_known_version(true);
    invalidation.set_is_trickle_restart(true);

    // Pick an arbitrary version number; it shouldn't really matter, but we
    // try not to make them correlated too much with the object name.
    invalidation.set_version(100 + ((i * 19) % 31));
    invalidations->push_back(invalidation);
  }
}

void UnitTestBase::MakeRegistrationStatusesFromObjectIds(
    const vector<ObjectIdP>& object_ids, bool is_reg, bool is_success,
    vector<RegistrationStatus>* registration_statuses) {
  for (size_t i = 0; i < object_ids.size(); ++i) {
    RegistrationStatus registration_status;
    registration_status.mutable_registration()->mutable_object_id()->CopyFrom(
        object_ids[i]);
    registration_status.mutable_registration()->set_op_type(
        is_reg ? RegistrationP::REGISTER : RegistrationP::UNREGISTER);
    registration_status.mutable_status()->set_code(
        is_success ? StatusP::SUCCESS : StatusP::TRANSIENT_FAILURE);
    registration_statuses->push_back(registration_status);
  }
}

TimeDelta UnitTestBase::GetMaxDelay(int delay_ms) {
  int64 extra_delay_ms = (delay_ms * kDefaultSmearPercent) / 100.0;
  return TimeDelta::FromMilliseconds(extra_delay_ms + delay_ms);
}

TimeDelta UnitTestBase::GetMaxBatchingDelay(
    const ProtocolHandlerConfigP& config) {
  return GetMaxDelay(config.batching_delay_ms());
}

void UnitTestBase::InitZeroRegistrationSummary(RegistrationSummary* summary) {
  summary->set_num_registrations(0);
  // "\3329..." can trigger MSVC to warn about "octal escape sequence terminated
  // by decimal number", so break the string between the two to avoid the
  // warning.
  string zero_digest(
      "\332" "9\243\356^kK\r2U\277\357\225`\030\220\257\330\007\t");
  summary->set_registration_digest(zero_digest);
}

void UnitTestBase::InitServerHeader(const string& token, ServerHeader* header) {
  ProtoHelpers::InitProtocolVersion(header->mutable_protocol_version());
  header->set_client_token(token);
  if (reg_summary.get() != NULL) {
    header->mutable_registration_summary()->CopyFrom(*reg_summary.get());
  }

  // Use arbitrary server time and message id, since they don't matter.
  header->set_server_time_ms(314159265);
  header->set_message_id("message-id-for-test");
}

bool UnitTestBase::CompareMessages(
    const ::google::protobuf::MessageLite& expected,
    const ::google::protobuf::MessageLite& actual) {
  // TODO: Fill in proper implementation.
  return true;
}

void UnitTestBase::ProcessIncomingMessage(const ServerToClientMessage& message,
    TimeDelta delay) {
  string serialized;
  message.SerializeToString(&serialized);
  message_callback->Run(serialized);
  internal_scheduler->PassTime(delay);
}

Matcher<ClientHeader> UnitTestBase::ClientHeaderMatches(
    const ClientHeader* header) {
  return AllOf(Property(&ClientHeader::protocol_version,
                        EqualsProto(header->protocol_version())),
               Property(&ClientHeader::registration_summary,
                        EqualsProto(header->registration_summary())),
               Property(&ClientHeader::max_known_server_time_ms,
                        header->max_known_server_time_ms()),
               Property(&ClientHeader::message_id,
                        header->message_id()));
}

}  // namespace invalidation
