// Copyright 2014 The Chromium OS 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 "buffet/device_registration_info.h"

#include <base/json/json_reader.h>
#include <base/json/json_writer.h>
#include <base/message_loop/message_loop.h>
#include <base/run_loop.h>
#include <base/values.h>
#include <chromeos/bind_lambda.h>
#include <chromeos/http/http_request.h>
#include <chromeos/http/http_transport_fake.h>
#include <chromeos/key_value_store.h>
#include <chromeos/mime_utils.h>
#include <gtest/gtest.h>

#include "buffet/commands/command_manager.h"
#include "buffet/commands/unittest_utils.h"
#include "buffet/states/mock_state_change_queue_interface.h"
#include "buffet/states/state_manager.h"
#include "buffet/storage_impls.h"

namespace buffet {

using chromeos::http::request_header::kAuthorization;
using chromeos::http::fake::ServerRequest;
using chromeos::http::fake::ServerResponse;

namespace {

namespace test_data {

const char kServiceURL[]           = "http://gcd.server.com/";
const char kOAuthURL[]             = "http://oauth.server.com/";
const char kApiKey[]               = "GOadRdTf9FERf0k4w6EFOof56fUJ3kFDdFL3d7f";
const char kClientId[]             = "123543821385-sfjkjshdkjhfk234sdfsdfkskd"
                                     "fkjh7f.apps.googleusercontent.com";
const char kClientSecret[]         = "5sdGdGlfolGlrFKfdFlgP6FG";
const char kDeviceId[]             = "4a7ea2d1-b331-1e1f-b206-e863c7635196";
const char kClaimTicketId[]        = "RTcUE";
const char kAccessToken[]          = "ya29.1.AADtN_V-dLUM-sVZ0qVjG9Dxm5NgdS9J"
                                     "Mx_JLUqhC9bED_YFjzHZtYt65ZzXCS35NMAeaVZ"
                                     "Dei530-w0yE2urpQ";
const char kRefreshToken[]         = "1/zQmxR6PKNvhcxf9SjXUrCjcmCrcqRKXctc6cp"
                                     "1nI-GQ";
const char kRobotAccountAuthCode[] = "4/Mf_ujEhPejVhOq-OxW9F5cSOnWzx."
                                     "YgciVjTYGscRshQV0ieZDAqiTIjMigI";
const char kRobotAccountEmail[]    = "6ed0b3f54f9bd619b942f4ad2441c252@"
                                     "clouddevices.gserviceaccount.com";
const char kUserAccountAuthCode[]  = "2/sd_GD1TGFKpJOLJ34-0g5fK0fflp.GlT"
                                     "I0F5g7hNtFgj5HFGOf8FlGK9eflO";
const char kUserAccessToken[]      = "sd56.4.FGDjG_F-gFGF-dFG6gGOG9Dxm5NgdS9"
                                     "JMx_JLUqhC9bED_YFjLKjlkjLKJlkjLKjlKJea"
                                     "VZDei530-w0yE2urpQ";
const char kUserRefreshToken[]     = "1/zQLKjlKJlkLkLKjLkjLKjLkjLjLkjl0ftc6"
                                     "cp1nI-GQ";
}  // namespace test_data

// Add the test device registration information.
void SetDefaultDeviceRegistration(base::DictionaryValue* data) {
  data->SetString("refresh_token", test_data::kRefreshToken);
  data->SetString("device_id", test_data::kDeviceId);
  data->SetString("robot_account", test_data::kRobotAccountEmail);
}

void OAuth2Handler(const ServerRequest& request, ServerResponse* response) {
  base::DictionaryValue json;
  if (request.GetFormField("grant_type") == "refresh_token") {
    // Refresh device access token.
    EXPECT_EQ(test_data::kRefreshToken, request.GetFormField("refresh_token"));
    EXPECT_EQ(test_data::kClientId, request.GetFormField("client_id"));
    EXPECT_EQ(test_data::kClientSecret, request.GetFormField("client_secret"));
    json.SetString("access_token", test_data::kAccessToken);
  } else if (request.GetFormField("grant_type") == "authorization_code") {
    // Obtain access token.
    std::string code = request.GetFormField("code");
    if (code == test_data::kUserAccountAuthCode) {
      // Get user access token.
      EXPECT_EQ(test_data::kClientId, request.GetFormField("client_id"));
      EXPECT_EQ(test_data::kClientSecret,
                request.GetFormField("client_secret"));
      EXPECT_EQ("urn:ietf:wg:oauth:2.0:oob",
                request.GetFormField("redirect_uri"));
      json.SetString("access_token", test_data::kUserAccessToken);
      json.SetString("token_type", "Bearer");
      json.SetString("refresh_token", test_data::kUserRefreshToken);
    } else if (code == test_data::kRobotAccountAuthCode) {
      // Get device access token.
      EXPECT_EQ(test_data::kClientId, request.GetFormField("client_id"));
      EXPECT_EQ(test_data::kClientSecret,
                request.GetFormField("client_secret"));
      EXPECT_EQ("oob", request.GetFormField("redirect_uri"));
      EXPECT_EQ("https://www.googleapis.com/auth/clouddevices",
                request.GetFormField("scope"));
      json.SetString("access_token", test_data::kAccessToken);
      json.SetString("token_type", "Bearer");
      json.SetString("refresh_token", test_data::kRefreshToken);
    } else {
      FAIL() << "Unexpected authorization code";
    }
  } else {
    FAIL() << "Unexpected grant type";
  }
  json.SetInteger("expires_in", 3600);
  response->ReplyJson(chromeos::http::status_code::Ok, &json);
}

void OAuth2HandlerFail(const ServerRequest& request,
                       ServerResponse* response) {
  base::DictionaryValue json;
  EXPECT_EQ("refresh_token", request.GetFormField("grant_type"));
  EXPECT_EQ(test_data::kRefreshToken, request.GetFormField("refresh_token"));
  EXPECT_EQ(test_data::kClientId, request.GetFormField("client_id"));
  EXPECT_EQ(test_data::kClientSecret, request.GetFormField("client_secret"));
  json.SetString("error", "unable_to_authenticate");
  response->ReplyJson(chromeos::http::status_code::BadRequest, &json);
}

void OAuth2HandlerDeregister(const ServerRequest& request,
                             ServerResponse* response) {
  base::DictionaryValue json;
  EXPECT_EQ("refresh_token", request.GetFormField("grant_type"));
  EXPECT_EQ(test_data::kRefreshToken, request.GetFormField("refresh_token"));
  EXPECT_EQ(test_data::kClientId, request.GetFormField("client_id"));
  EXPECT_EQ(test_data::kClientSecret, request.GetFormField("client_secret"));
  json.SetString("error", "invalid_grant");
  response->ReplyJson(chromeos::http::status_code::BadRequest, &json);
}

void DeviceInfoHandler(const ServerRequest& request, ServerResponse* response) {
  std::string auth = "Bearer ";
  auth += test_data::kAccessToken;
  EXPECT_EQ(auth,
            request.GetHeader(chromeos::http::request_header::kAuthorization));
  response->ReplyJson(chromeos::http::status_code::Ok, {
    {"channel.supportedType", "xmpp"},
    {"deviceKind", "vendor"},
    {"id", test_data::kDeviceId},
    {"kind", "clouddevices#device"},
  });
}

void FinalizeTicketHandler(const ServerRequest& request,
                           ServerResponse* response) {
  EXPECT_EQ(test_data::kApiKey, request.GetFormField("key"));
  EXPECT_TRUE(request.GetData().empty());

  response->ReplyJson(chromeos::http::status_code::Ok, {
    {"id", test_data::kClaimTicketId},
    {"kind", "clouddevices#registrationTicket"},
    {"oauthClientId", test_data::kClientId},
    {"userEmail", "user@email.com"},
    {"deviceDraft.id", test_data::kDeviceId},
    {"deviceDraft.kind", "clouddevices#device"},
    {"deviceDraft.channel.supportedType", "xmpp"},
    {"robotAccountEmail", test_data::kRobotAccountEmail},
    {"robotAccountAuthorizationCode", test_data::kRobotAccountAuthCode},
  });
}

}  // anonymous namespace

class DeviceRegistrationInfoTest : public ::testing::Test {
 protected:
  void SetUp() override {
    std::unique_ptr<StorageInterface> storage{new MemStorage};
    storage_ = storage.get();
    storage->Save(data_);
    transport_ = std::make_shared<chromeos::http::fake::Transport>();
    command_manager_ = std::make_shared<CommandManager>();
    state_manager_ = std::make_shared<StateManager>(&mock_state_change_queue_);

    std::unique_ptr<BuffetConfig> config{new BuffetConfig{std::move(storage)}};
    config_ = config.get();
    dev_reg_.reset(new DeviceRegistrationInfo{command_manager_, state_manager_,
                                              std::move(config), transport_,
                                              true, nullptr});

    ReloadConfig();
  }

  void ReloadConfig() {
    chromeos::KeyValueStore config_store;
    config_store.SetString("client_id", test_data::kClientId);
    config_store.SetString("client_secret", test_data::kClientSecret);
    config_store.SetString("api_key", test_data::kApiKey);
    config_store.SetString("device_kind",  "vendor");
    config_store.SetString("name",  "Coffee Pot");
    config_store.SetString("description", "Easy to clean");
    config_store.SetString("location", "Kitchen");
    config_store.SetString("local_anonymous_access_role", "viewer");
    config_store.SetString("model_id", "AAAAA");
    config_store.SetString("oauth_url", test_data::kOAuthURL);
    config_store.SetString("service_url", test_data::kServiceURL);
    config_->Load(config_store);
    dev_reg_->Start();
  }

  void PublishCommands(const base::ListValue& commands) {
    return dev_reg_->PublishCommands(commands);
  }

  bool RefreshAccessToken(chromeos::ErrorPtr* error) const {
    base::MessageLoopForIO message_loop;
    base::RunLoop run_loop;

    bool succeeded = false;
    auto on_success = [&run_loop, &succeeded]() {
      succeeded = true;
      run_loop.Quit();
    };
    auto on_failure = [&run_loop, &error](const chromeos::Error* in_error) {
      if (error)
        *error = in_error->Clone();
      run_loop.Quit();
    };
    dev_reg_->RefreshAccessToken(base::Bind(on_success),
                                 base::Bind(on_failure));
    run_loop.Run();
    return succeeded;
  }

  void SetAccessToken() {
    dev_reg_->access_token_ = test_data::kAccessToken;
  }

  RegistrationStatus GetRegistrationStatus() const {
    return dev_reg_->registration_status_;
  }

  base::DictionaryValue data_;
  StorageInterface* storage_{nullptr};
  BuffetConfig* config_{nullptr};
  std::shared_ptr<chromeos::http::fake::Transport> transport_;
  std::unique_ptr<DeviceRegistrationInfo> dev_reg_;
  std::shared_ptr<CommandManager> command_manager_;
  testing::NiceMock<MockStateChangeQueueInterface> mock_state_change_queue_;
  std::shared_ptr<StateManager> state_manager_;
};

////////////////////////////////////////////////////////////////////////////////
TEST_F(DeviceRegistrationInfoTest, GetServiceURL) {
  EXPECT_EQ(test_data::kServiceURL, dev_reg_->GetServiceURL());
  std::string url = test_data::kServiceURL;
  url += "registrationTickets";
  EXPECT_EQ(url, dev_reg_->GetServiceURL("registrationTickets"));
  url += "?key=";
  url += test_data::kApiKey;
  EXPECT_EQ(url, dev_reg_->GetServiceURL("registrationTickets", {
    {"key", test_data::kApiKey}
  }));
  url += "&restart=true";
  EXPECT_EQ(url, dev_reg_->GetServiceURL("registrationTickets", {
    {"key", test_data::kApiKey},
    {"restart", "true"},
  }));
}

TEST_F(DeviceRegistrationInfoTest, GetOAuthURL) {
  EXPECT_EQ(test_data::kOAuthURL, dev_reg_->GetOAuthURL());
  std::string url = test_data::kOAuthURL;
  url += "auth?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fclouddevices&";
  url += "redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&";
  url += "response_type=code&";
  url += "client_id=";
  url += test_data::kClientId;
  EXPECT_EQ(url, dev_reg_->GetOAuthURL("auth", {
    {"scope", "https://www.googleapis.com/auth/clouddevices"},
    {"redirect_uri", "urn:ietf:wg:oauth:2.0:oob"},
    {"response_type", "code"},
    {"client_id", test_data::kClientId}
  }));
}

TEST_F(DeviceRegistrationInfoTest, HaveRegistrationCredentials) {
  EXPECT_FALSE(dev_reg_->HaveRegistrationCredentials(nullptr));
  EXPECT_EQ(0, transport_->GetRequestCount());

  SetDefaultDeviceRegistration(&data_);
  storage_->Save(data_);
  ReloadConfig();

  transport_->AddHandler(dev_reg_->GetOAuthURL("token"),
                         chromeos::http::request_type::kPost,
                         base::Bind(OAuth2Handler));
  transport_->ResetRequestCount();
  EXPECT_TRUE(RefreshAccessToken(nullptr));
  EXPECT_EQ(1, transport_->GetRequestCount());
  EXPECT_TRUE(dev_reg_->HaveRegistrationCredentials(nullptr));
}

TEST_F(DeviceRegistrationInfoTest, CheckAuthenticationFailure) {
  SetDefaultDeviceRegistration(&data_);
  storage_->Save(data_);
  ReloadConfig();
  EXPECT_EQ(RegistrationStatus::kConnecting, GetRegistrationStatus());

  transport_->AddHandler(dev_reg_->GetOAuthURL("token"),
                         chromeos::http::request_type::kPost,
                         base::Bind(OAuth2HandlerFail));
  transport_->ResetRequestCount();
  chromeos::ErrorPtr error;
  EXPECT_FALSE(RefreshAccessToken(&error));
  EXPECT_EQ(1, transport_->GetRequestCount());
  EXPECT_TRUE(error->HasError(kErrorDomainOAuth2, "unable_to_authenticate"));
  EXPECT_EQ(RegistrationStatus::kConnecting, GetRegistrationStatus());
}

TEST_F(DeviceRegistrationInfoTest, CheckDeregistration) {
  SetDefaultDeviceRegistration(&data_);
  storage_->Save(data_);
  ReloadConfig();
  EXPECT_EQ(RegistrationStatus::kConnecting, GetRegistrationStatus());

  transport_->AddHandler(dev_reg_->GetOAuthURL("token"),
                         chromeos::http::request_type::kPost,
                         base::Bind(OAuth2HandlerDeregister));
  transport_->ResetRequestCount();
  chromeos::ErrorPtr error;
  EXPECT_FALSE(RefreshAccessToken(&error));
  EXPECT_EQ(1, transport_->GetRequestCount());
  EXPECT_TRUE(error->HasError(kErrorDomainOAuth2, "invalid_grant"));
  EXPECT_EQ(RegistrationStatus::kInvalidCredentials, GetRegistrationStatus());
}

TEST_F(DeviceRegistrationInfoTest, GetDeviceInfo) {
  SetDefaultDeviceRegistration(&data_);
  storage_->Save(data_);
  ReloadConfig();
  SetAccessToken();

  transport_->AddHandler(dev_reg_->GetDeviceURL(),
                         chromeos::http::request_type::kGet,
                         base::Bind(DeviceInfoHandler));
  transport_->ResetRequestCount();
  base::MessageLoopForIO message_loop;
  base::RunLoop run_loop;

  bool succeeded = false;
  auto on_success =
      [&run_loop, &succeeded, this](const base::DictionaryValue& info) {
    EXPECT_EQ(1, transport_->GetRequestCount());
    std::string id;
    EXPECT_TRUE(info.GetString("id", &id));
    EXPECT_EQ(test_data::kDeviceId, id);
    succeeded = true;
    run_loop.Quit();
  };
  auto on_failure = [&run_loop](const chromeos::Error* error) {
    run_loop.Quit();
    FAIL() << "Should not be called";
  };
  dev_reg_->GetDeviceInfo(base::Bind(on_success), base::Bind(on_failure));
  run_loop.Run();
  EXPECT_TRUE(succeeded);
}

TEST_F(DeviceRegistrationInfoTest, RegisterDevice) {
  auto update_ticket = [](const ServerRequest& request,
                          ServerResponse* response) {
    EXPECT_EQ(test_data::kApiKey, request.GetFormField("key"));
    auto json = request.GetDataAsJson();
    EXPECT_NE(nullptr, json.get());
    std::string value;
    EXPECT_TRUE(json->GetString("id", &value));
    EXPECT_EQ(test_data::kClaimTicketId, value);
    EXPECT_TRUE(json->GetString("deviceDraft.channel.supportedType", &value));
    EXPECT_EQ("pull", value);
    EXPECT_TRUE(json->GetString("oauthClientId", &value));
    EXPECT_EQ(test_data::kClientId, value);
    EXPECT_TRUE(json->GetString("deviceDraft.deviceKind", &value));
    EXPECT_EQ("vendor", value);
    EXPECT_TRUE(json->GetString("deviceDraft.description", &value));
    EXPECT_EQ("Easy to clean", value);
    EXPECT_TRUE(json->GetString("deviceDraft.location", &value));
    EXPECT_EQ("Kitchen", value);
    EXPECT_TRUE(json->GetString("deviceDraft.modelManifestId", &value));
    EXPECT_EQ("AAAAA", value);
    EXPECT_TRUE(json->GetString("deviceDraft.name", &value));
    EXPECT_EQ("Coffee Pot", value);
    base::DictionaryValue* commandDefs = nullptr;
    EXPECT_TRUE(json->GetDictionary("deviceDraft.commandDefs", &commandDefs));
    EXPECT_FALSE(commandDefs->empty());

    auto expected = R"({
      'base': {
        'reboot': {
          'parameters': {
            'delay': {
              'minimum': 10,
              'type': 'integer'
            }
          },
          'minimalRole': 'user'
        }
      },
      'robot': {
        '_jump': {
          'parameters': {
            '_height': {
              'type': 'integer'
            }
          },
          'minimalRole': 'user'
        }
      }
    })";
    EXPECT_JSON_EQ(expected, *commandDefs);

    base::DictionaryValue json_resp;
    json_resp.SetString("id", test_data::kClaimTicketId);
    json_resp.SetString("kind", "clouddevices#registrationTicket");
    json_resp.SetString("oauthClientId", test_data::kClientId);
    base::DictionaryValue* device_draft = nullptr;
    EXPECT_TRUE(json->GetDictionary("deviceDraft", &device_draft));
    device_draft = device_draft->DeepCopy();
    device_draft->SetString("id", test_data::kDeviceId);
    device_draft->SetString("kind", "clouddevices#device");
    json_resp.Set("deviceDraft", device_draft);

    response->ReplyJson(chromeos::http::status_code::Ok, &json_resp);
  };

  auto json_base = unittests::CreateDictionaryValue(R"({
    'base': {
      'reboot': {
        'parameters': {'delay': 'integer'},
        'minimalRole': 'user',
        'results': {}
      },
      'shutdown': {
        'parameters': {},
        'minimalRole': 'user',
        'results': {}
      }
    }
  })");
  EXPECT_TRUE(command_manager_->LoadBaseCommands(*json_base, nullptr));
  auto json_cmds = unittests::CreateDictionaryValue(R"({
    'base': {
      'reboot': {
        'parameters': {'delay': {'minimum': 10}},
        'minimalRole': 'user',
        'results': {}
      }
    },
    'robot': {
      '_jump': {
        'parameters': {'_height': 'integer'},
        'minimalRole': 'user',
        'results': {}
      }
    }
  })");
  EXPECT_TRUE(command_manager_->LoadCommands(*json_cmds, "", nullptr));

  transport_->AddHandler(dev_reg_->GetServiceURL(
      std::string("registrationTickets/") + test_data::kClaimTicketId),
      chromeos::http::request_type::kPatch,
      base::Bind(update_ticket));
  std::string ticket_url =
      dev_reg_->GetServiceURL("registrationTickets/" +
                             std::string(test_data::kClaimTicketId));
  transport_->AddHandler(ticket_url + "/finalize",
                         chromeos::http::request_type::kPost,
                         base::Bind(FinalizeTicketHandler));

  transport_->AddHandler(dev_reg_->GetOAuthURL("token"),
                         chromeos::http::request_type::kPost,
                         base::Bind(OAuth2Handler));
  std::string device_id =
      dev_reg_->RegisterDevice(test_data::kClaimTicketId, nullptr);

  EXPECT_EQ(test_data::kDeviceId, device_id);
  EXPECT_EQ(3, transport_->GetRequestCount());
  EXPECT_EQ(RegistrationStatus::kConnecting, GetRegistrationStatus());

  // Validate the device info saved to storage...
  auto storage_data = storage_->Load();
  base::DictionaryValue* dict = nullptr;
  EXPECT_TRUE(storage_data->GetAsDictionary(&dict));
  std::string value;
  EXPECT_TRUE(dict->GetString("device_id", &value));
  EXPECT_EQ(test_data::kDeviceId, value);
  EXPECT_TRUE(dict->GetString("refresh_token", &value));
  EXPECT_EQ(test_data::kRefreshToken, value);
  EXPECT_TRUE(dict->GetString("robot_account", &value));
  EXPECT_EQ(test_data::kRobotAccountEmail, value);
}

TEST_F(DeviceRegistrationInfoTest, OOBRegistrationStatus) {
  // After we've been initialized, we should be either offline or unregistered,
  // depending on whether or not we've found credentials.
  EXPECT_EQ(RegistrationStatus::kUnconfigured, GetRegistrationStatus());
  // Put some credentials into our state, make sure we call that offline.
  SetDefaultDeviceRegistration(&data_);
  storage_->Save(data_);
  ReloadConfig();
  EXPECT_EQ(RegistrationStatus::kConnecting, GetRegistrationStatus());
}

TEST_F(DeviceRegistrationInfoTest, UpdateCommand) {
  SetDefaultDeviceRegistration(&data_);
  storage_->Save(data_);
  ReloadConfig();
  SetAccessToken();

  auto json_cmds = unittests::CreateDictionaryValue(R"({
    'robot': {
      '_jump': {
        'parameters': {'_height': 'integer'},
        'results': {'status': 'string'},
        'minimalRole': 'user'
      }
    }
  })");
  EXPECT_TRUE(command_manager_->LoadCommands(*json_cmds, "", nullptr));

  const std::string command_url = dev_reg_->GetServiceURL("commands/1234");

  auto commands_json = unittests::CreateValue(R"([{
    'name':'robot._jump',
    'id':'1234',
    'parameters': {'_height': 100},
    'minimalRole': 'user'
  }])");
  ASSERT_NE(nullptr, commands_json.get());
  const base::ListValue* command_list = nullptr;
  ASSERT_TRUE(commands_json->GetAsList(&command_list));
  PublishCommands(*command_list);
  auto command = command_manager_->FindCommand("1234");
  ASSERT_NE(nullptr, command);
  StringPropType string_type;
  native_types::Object results{
    {"status", string_type.CreateValue(std::string{"Ok"}, nullptr)}
  };

  // UpdateCommand when setting command results.
  auto update_command_results = [](const ServerRequest& request,
                                   ServerResponse* response) {
    EXPECT_EQ(R"({"results":{"status":"Ok"}})",
              request.GetDataAsNormalizedJsonString());
    response->ReplyJson(chromeos::http::status_code::Ok,
                        chromeos::http::FormFieldList{});
  };

  transport_->AddHandler(command_url,
                         chromeos::http::request_type::kPatch,
                         base::Bind(update_command_results));

  command->SetResults(results);

  // UpdateCommand when setting command progress.
  int count = 0;  // This will be called twice...
  auto update_command_progress = [&count](const ServerRequest& request,
                                          ServerResponse* response) {
    if (count++ == 0) {
      EXPECT_EQ(R"({"state":"inProgress"})",
                request.GetDataAsNormalizedJsonString());
    } else {
      EXPECT_EQ(R"({"progress":{"progress":18}})",
                request.GetDataAsNormalizedJsonString());
    }
    response->ReplyJson(chromeos::http::status_code::Ok,
                        chromeos::http::FormFieldList{});
  };

  transport_->AddHandler(command_url,
                         chromeos::http::request_type::kPatch,
                         base::Bind(update_command_progress));

  native_types::Object progress{
      {"progress", unittests::make_int_prop_value(18)}};
  command->SetProgress(progress);

  // UpdateCommand when changing command status.
  auto update_command_state = [](const ServerRequest& request,
                                 ServerResponse* response) {
    EXPECT_EQ(R"({"state":"cancelled"})",
              request.GetDataAsNormalizedJsonString());
    response->ReplyJson(chromeos::http::status_code::Ok,
                        chromeos::http::FormFieldList{});
  };

  transport_->AddHandler(command_url,
                         chromeos::http::request_type::kPatch,
                         base::Bind(update_command_state));

  command->Cancel();
}


}  // namespace buffet
