18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// Copyright (c) 2012 The Chromium Authors. All rights reserved.
28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// Use of this source code is governed by a BSD-style license that can be
38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// found in the LICENSE file.
48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddcr.define('cloudprint', function() {
68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  'use strict';
78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  /** Namespace which contains a method to parse cloud destinations directly. */
98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  function CloudDestinationParser() {};
108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  /**
128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * Enumeration of cloud destination field names.
138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * @enum {string}
148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * @private
158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   */
168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  CloudDestinationParser.Field_ = {
178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    CAPABILITIES: 'capabilities',
188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    CONNECTION_STATUS: 'connectionStatus',
198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    DESCRIPTION: 'description',
208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    DISPLAY_NAME: 'displayName',
218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    ID: 'id',
228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    IS_TOS_ACCEPTED: 'isTosAccepted',
238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    LAST_ACCESS: 'accessTime',
248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    TAGS: 'tags',
258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    TYPE: 'type'
268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  };
278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  /**
298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * Special tag that denotes whether the destination has been recently used.
308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * @type {string}
318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * @const
328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * @private
338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   */
348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  CloudDestinationParser.RECENT_TAG_ = '^recent';
358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  /**
378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * Special tag that denotes whether the destination is owned by the user.
388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * @type {string}
398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * @const
408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * @private
418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   */
428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  CloudDestinationParser.OWNED_TAG_ = '^own';
438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  /**
458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * Enumeration of cloud destination types that are supported by print preview.
468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * @enum {string}
478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * @private
488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   */
498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  CloudDestinationParser.CloudType_ = {
508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    ANDROID: 'ANDROID_CHROME_SNAPSHOT',
518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    DOCS: 'DOCS',
528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    IOS: 'IOS_CHROME_SNAPSHOT'
538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  };
548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  /**
568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * Parses a destination from JSON from a Google Cloud Print search or printer
578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * response.
588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * @param {!Object} json Object that represents a Google Cloud Print search or
598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   *     printer response.
608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * @param {!print_preview.Destination.Origin} origin The origin of the
618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   *     response.
628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * @param {string} account The account this destination is registered for or
638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   *     empty string, if origin != COOKIES.
648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   * @return {!print_preview.Destination} Parsed destination.
658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd   */
668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  CloudDestinationParser.parse = function(json, origin, account) {
678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    if (!json.hasOwnProperty(CloudDestinationParser.Field_.ID) ||
688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd        !json.hasOwnProperty(CloudDestinationParser.Field_.TYPE) ||
698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd        !json.hasOwnProperty(CloudDestinationParser.Field_.DISPLAY_NAME)) {
708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd      throw Error('Cloud destination does not have an ID or a display name');
718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    }
728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    var id = json[CloudDestinationParser.Field_.ID];
738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    var tags = json[CloudDestinationParser.Field_.TAGS] || [];
748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    var connectionStatus =
758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd        json[CloudDestinationParser.Field_.CONNECTION_STATUS] ||
768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd        print_preview.Destination.ConnectionStatus.UNKNOWN;
778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    var optionalParams = {
788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd      account: account,
79      tags: tags,
80      isOwned: arrayContains(tags, CloudDestinationParser.OWNED_TAG_),
81      lastAccessTime: parseInt(
82          json[CloudDestinationParser.Field_.LAST_ACCESS], 10) || Date.now(),
83      isTosAccepted: (id == print_preview.Destination.GooglePromotedId.FEDEX) ?
84          json[CloudDestinationParser.Field_.IS_TOS_ACCEPTED] : null,
85      cloudID: id,
86      description: json[CloudDestinationParser.Field_.DESCRIPTION]
87    };
88    var cloudDest = new print_preview.Destination(
89        id,
90        CloudDestinationParser.parseType_(
91            json[CloudDestinationParser.Field_.TYPE]),
92        origin,
93        json[CloudDestinationParser.Field_.DISPLAY_NAME],
94        arrayContains(tags, CloudDestinationParser.RECENT_TAG_) /*isRecent*/,
95        connectionStatus,
96        optionalParams);
97    if (json.hasOwnProperty(CloudDestinationParser.Field_.CAPABILITIES)) {
98      cloudDest.capabilities = /** @type {!print_preview.Cdd} */(
99          json[CloudDestinationParser.Field_.CAPABILITIES]);
100    }
101    return cloudDest;
102  };
103
104  /**
105   * Parses the destination type.
106   * @param {string} typeStr Destination type given by the Google Cloud Print
107   *     server.
108   * @return {!print_preview.Destination.Type} Destination type.
109   * @private
110   */
111  CloudDestinationParser.parseType_ = function(typeStr) {
112    if (typeStr == CloudDestinationParser.CloudType_.ANDROID ||
113        typeStr == CloudDestinationParser.CloudType_.IOS) {
114      return print_preview.Destination.Type.MOBILE;
115    } else if (typeStr == CloudDestinationParser.CloudType_.DOCS) {
116      return print_preview.Destination.Type.GOOGLE_PROMOTED;
117    } else {
118      return print_preview.Destination.Type.GOOGLE;
119    }
120  };
121
122  /** Namespace which contains a method to parse printer sharing invitation. */
123  function InvitationParser() {};
124
125  /**
126   * Enumeration of invitation field names.
127   * @enum {string}
128   * @private
129   */
130  InvitationParser.Field_ = {
131    PRINTER: 'printer',
132    RECEIVER: 'receiver',
133    SENDER: 'sender'
134  };
135
136  /**
137   * Enumeration of cloud destination types that are supported by print preview.
138   * @enum {string}
139   * @private
140   */
141  InvitationParser.AclType_ = {
142    DOMAIN: 'DOMAIN',
143    GROUP: 'GROUP',
144    PUBLIC: 'PUBLIC',
145    USER: 'USER'
146  };
147
148  /**
149   * Parses printer sharing invitation from JSON from GCP invite API response.
150   * @param {!Object} json Object that represents a invitation search response.
151   * @param {string} account The account this invitation is sent for.
152   * @return {!print_preview.Invitation} Parsed invitation.
153   */
154  InvitationParser.parse = function(json, account) {
155    if (!json.hasOwnProperty(InvitationParser.Field_.SENDER) ||
156        !json.hasOwnProperty(InvitationParser.Field_.RECEIVER) ||
157        !json.hasOwnProperty(InvitationParser.Field_.PRINTER)) {
158      throw Error('Invitation does not have necessary info.');
159    }
160
161    var nameFormatter = function(name, scope) {
162      return name && scope ? (name + ' (' + scope + ')') : (name || scope);
163    };
164
165    var sender = json[InvitationParser.Field_.SENDER];
166    var senderName = nameFormatter(sender['name'], sender['email']);
167
168    var receiver = json[InvitationParser.Field_.RECEIVER];
169    var receiverName = '';
170    var receiverType = receiver['type'];
171    if (receiverType == InvitationParser.AclType_.USER) {
172      // It's a personal invitation, empty name indicates just that.
173    } else if (receiverType == InvitationParser.AclType_.GROUP ||
174               receiverType == InvitationParser.AclType_.DOMAIN) {
175      receiverName = nameFormatter(receiver['name'], receiver['scope']);
176    } else {
177      throw Error('Invitation of unsupported receiver type');
178    }
179
180    var destination = cloudprint.CloudDestinationParser.parse(
181        json[InvitationParser.Field_.PRINTER],
182        print_preview.Destination.Origin.COOKIES,
183        account);
184
185    return new print_preview.Invitation(
186        senderName, receiverName, destination, receiver, account);
187  };
188
189  // Export
190  return {
191    CloudDestinationParser: CloudDestinationParser,
192    InvitationParser: InvitationParser
193  };
194});
195