1// Copyright 2013 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 "components/autofill/content/browser/wallet/instrument.h"
6
7#include "base/logging.h"
8#include "base/strings/string_number_conversions.h"
9#include "base/strings/string_util.h"
10#include "base/strings/utf_string_conversions.h"
11#include "base/values.h"
12#include "components/autofill/content/browser/wallet/wallet_address.h"
13#include "components/autofill/core/browser/autofill_country.h"
14#include "components/autofill/core/browser/autofill_profile.h"
15#include "components/autofill/core/browser/credit_card.h"
16#include "components/autofill/core/browser/validation.h"
17
18namespace autofill {
19namespace wallet {
20
21namespace {
22
23// Converts a known Autofill card type to a Instrument::FormOfPayment.
24// Used for creating new Instruments.
25Instrument::FormOfPayment FormOfPaymentFromCardType(const std::string& type) {
26  if (type == kAmericanExpressCard)
27    return Instrument::AMEX;
28  else if (type == kDiscoverCard)
29    return Instrument::DISCOVER;
30  else if (type == kMasterCard)
31    return Instrument::MASTER_CARD;
32  else if (type == kVisaCard)
33    return Instrument::VISA;
34
35  return Instrument::UNKNOWN;
36}
37
38std::string FormOfPaymentToString(Instrument::FormOfPayment form_of_payment) {
39  switch (form_of_payment) {
40    case Instrument::UNKNOWN:
41      return "UNKNOWN";
42    case Instrument::VISA:
43      return "VISA";
44    case Instrument::MASTER_CARD:
45      return "MASTER_CARD";
46    case Instrument::AMEX:
47      return "AMEX";
48    case Instrument::DISCOVER:
49      return "DISCOVER";
50    case Instrument::JCB:
51      return "JCB";
52  }
53  NOTREACHED();
54  return "NOT_POSSIBLE";
55}
56
57}  // namespace
58
59Instrument::Instrument(const CreditCard& card,
60                       const base::string16& card_verification_number,
61                       const AutofillProfile& profile)
62    : primary_account_number_(card.GetRawInfo(CREDIT_CARD_NUMBER)),
63      card_verification_number_(card_verification_number),
64      expiration_month_(card.expiration_month()),
65      expiration_year_(card.expiration_year()),
66      form_of_payment_(FormOfPaymentFromCardType(card.type())),
67      address_(new Address(profile)) {
68  Init();
69}
70
71Instrument::Instrument(const base::string16& primary_account_number,
72                       const base::string16& card_verification_number,
73                       int expiration_month,
74                       int expiration_year,
75                       FormOfPayment form_of_payment,
76                       scoped_ptr<Address> address)
77    : primary_account_number_(primary_account_number),
78      card_verification_number_(card_verification_number),
79      expiration_month_(expiration_month),
80      expiration_year_(expiration_year),
81      form_of_payment_(form_of_payment),
82      address_(address.Pass()) {
83  Init();
84}
85
86Instrument::Instrument(const Instrument& instrument)
87    : primary_account_number_(instrument.primary_account_number()),
88      card_verification_number_(instrument.card_verification_number()),
89      expiration_month_(instrument.expiration_month()),
90      expiration_year_(instrument.expiration_year()),
91      form_of_payment_(instrument.form_of_payment()),
92      address_(instrument.address() ?
93          new Address(*instrument.address()) : NULL) {
94  Init();
95}
96
97Instrument::~Instrument() {}
98
99scoped_ptr<base::DictionaryValue> Instrument::ToDictionary() const {
100  // |primary_account_number_| and |card_verification_number_| can never be
101  // sent the server in way that would require putting them into a dictionary.
102  // Never add them to this function.
103
104  scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
105  dict->SetString("type", "CREDIT_CARD");
106  dict->SetInteger("credit_card.exp_month", expiration_month_);
107  dict->SetInteger("credit_card.exp_year", expiration_year_);
108  dict->SetString("credit_card.fop_type",
109                  FormOfPaymentToString(form_of_payment_));
110  dict->SetString("credit_card.last_4_digits", last_four_digits_);
111  dict->Set("credit_card.address",
112            address_.get()->ToDictionaryWithoutID().release());
113
114  return dict.Pass();
115}
116
117void Instrument::Init() {
118  if (primary_account_number_.size() >= 4) {
119    last_four_digits_ =
120        primary_account_number_.substr(primary_account_number_.size() - 4);
121  }
122}
123
124}  // namespace wallet
125}  // namespace autofill
126