1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/local_discovery/privetv3_session.h"
6
7#include "base/json/json_writer.h"
8#include "base/logging.h"
9#include "base/message_loop/message_loop.h"
10#include "chrome/browser/local_discovery/privet_http.h"
11#include "chrome/common/cloud_print/cloud_print_constants.h"
12
13namespace local_discovery {
14
15namespace {
16
17const char kUrlPlaceHolder[] = "http://host/";
18
19const char kStubPrivetCode[] = "1234";
20
21GURL CreatePrivetURL(const std::string& path) {
22  GURL url(kUrlPlaceHolder);
23  GURL::Replacements replacements;
24  replacements.SetPathStr(path);
25  return url.ReplaceComponents(replacements);
26}
27
28}  // namespace
29
30class PrivetV3Session::FetcherDelegate : public PrivetURLFetcher::Delegate {
31 public:
32  FetcherDelegate(const base::WeakPtr<PrivetV3Session>& session,
33                  Request* request);
34  virtual ~FetcherDelegate();
35
36  // PrivetURLFetcher::Delegate methods.
37  virtual void OnNeedPrivetToken(
38      PrivetURLFetcher* fetcher,
39      const PrivetURLFetcher::TokenCallback& callback) OVERRIDE;
40  virtual void OnError(PrivetURLFetcher* fetcher,
41                       PrivetURLFetcher::ErrorType error) OVERRIDE;
42  virtual void OnParsedJson(PrivetURLFetcher* fetcher,
43                            const base::DictionaryValue& value,
44                            bool has_error) OVERRIDE;
45
46 private:
47  friend class PrivetV3Session;
48  scoped_ptr<PrivetURLFetcher> url_fetcher_;
49  base::WeakPtr<PrivetV3Session> session_;
50  Request* request_;
51};
52
53PrivetV3Session::FetcherDelegate::FetcherDelegate(
54    const base::WeakPtr<PrivetV3Session>& session,
55    Request* request)
56    : session_(session), request_(request) {
57}
58
59PrivetV3Session::FetcherDelegate::~FetcherDelegate() {
60}
61
62void PrivetV3Session::FetcherDelegate::OnNeedPrivetToken(
63    PrivetURLFetcher* fetcher,
64    const PrivetURLFetcher::TokenCallback& callback) {
65  if (session_)
66    session_->client_->RefreshPrivetToken(callback);
67}
68
69void PrivetV3Session::FetcherDelegate::OnError(
70    PrivetURLFetcher* fetcher,
71    PrivetURLFetcher::ErrorType error) {
72  request_->OnError(error);
73}
74
75void PrivetV3Session::FetcherDelegate::OnParsedJson(
76    PrivetURLFetcher* fetcher,
77    const base::DictionaryValue& value,
78    bool has_error) {
79  request_->OnParsedJson(value, has_error);
80}
81
82PrivetV3Session::Delegate::~Delegate() {
83}
84
85PrivetV3Session::Request::Request() {
86}
87
88PrivetV3Session::Request::~Request() {
89}
90
91PrivetV3Session::PrivetV3Session(scoped_ptr<PrivetHTTPClient> client,
92                                 Delegate* delegate)
93    : delegate_(delegate),
94      client_(client.Pass()),
95      code_confirmed_(false),
96      weak_ptr_factory_(this) {
97}
98
99PrivetV3Session::~PrivetV3Session() {
100}
101
102void PrivetV3Session::Start() {
103  base::MessageLoop::current()->PostDelayedTask(
104      FROM_HERE,
105      base::Bind(&PrivetV3Session::ConfirmFakeCode,
106                 weak_ptr_factory_.GetWeakPtr()),
107      base::TimeDelta::FromSeconds(1));
108}
109
110void PrivetV3Session::ConfirmCode(const std::string& code) {
111  if (code == kStubPrivetCode) {
112    code_confirmed_ = true;
113    delegate_->OnSessionStatus(extensions::api::gcd_private::STATUS_SUCCESS);
114  } else {
115    delegate_->OnSessionStatus(
116        extensions::api::gcd_private::STATUS_BADCONFIRMATIONCODEERROR);
117  }
118}
119
120void PrivetV3Session::StartRequest(Request* request) {
121  CHECK(code_confirmed_);
122
123  request->fetcher_delegate_.reset(
124      new FetcherDelegate(weak_ptr_factory_.GetWeakPtr(), request));
125
126  scoped_ptr<PrivetURLFetcher> url_fetcher =
127      client_->CreateURLFetcher(CreatePrivetURL(request->GetName()),
128                                net::URLFetcher::POST,
129                                request->fetcher_delegate_.get());
130  std::string json;
131  base::JSONWriter::WriteWithOptions(
132      &request->GetInput(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &json);
133  url_fetcher->SetUploadData(cloud_print::kContentTypeJSON, json);
134
135  request->fetcher_delegate_->url_fetcher_ = url_fetcher.Pass();
136  request->fetcher_delegate_->url_fetcher_->Start();
137}
138
139void PrivetV3Session::ConfirmFakeCode() {
140  delegate_->OnSetupConfirmationNeeded(
141      kStubPrivetCode,
142      extensions::api::gcd_private::CONFIRMATION_TYPE_DISPLAYCODE);
143}
144
145}  // namespace local_discovery
146