package org.atlasapi.application.auth.google;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.api.client.repackaged.com.google.common.base.Throwables;
import com.google.api.services.oauth2.model.Userinfo;
import com.metabroadcast.common.base.Maybe;
import com.metabroadcast.common.social.auth.credentials.AuthToken;
import com.metabroadcast.common.social.auth.facebook.AccessTokenChecker;
import com.metabroadcast.common.social.model.UserRef;
import com.metabroadcast.common.social.model.UserRef.UserNamespace;
import com.metabroadcast.common.social.user.ApplicationIdAwareUserRefBuilder;


public class GoogleAccessTokenChecker implements AccessTokenChecker {

    private final ApplicationIdAwareUserRefBuilder userRefBuilder;
    private final GoogleAuthClient googleClient;
    
    private static final Logger log = LoggerFactory.getLogger(GoogleAccessTokenChecker.class);
    
    public GoogleAccessTokenChecker(ApplicationIdAwareUserRefBuilder userRefBuilder,
            GoogleAuthClient googleClient) {
        super();
        this.userRefBuilder = checkNotNull(userRefBuilder);
        this.googleClient = checkNotNull(googleClient);
    }

    @Override
    public Maybe<UserRef> check(AuthToken accessToken) {
        checkArgument(accessToken.isFor(UserNamespace.GOOGLE));
        try {
            Userinfo user = googleClient.getUserForToken(accessToken);
            return Maybe.just(userRefBuilder.from(String.valueOf(user.getId()), UserNamespace.GOOGLE));
        } catch (IOException e) {
            Throwables.propagate(e);
            return null;
        }
    }

}

@@ -259,16 +259,90 @@
 ctory;%0A%0A
+import com.google.api.client.googleapis.json.GoogleJsonResponseException;%0A
 import c
@@ -506,16 +506,69 @@
 .Maybe;%0A
+import com.metabroadcast.common.http.HttpStatusCode;%0A
 import c
@@ -1804,18 +1804,34 @@
  catch (
-IO
+GoogleJsonResponse
 Exceptio
@@ -1853,30 +1853,453 @@
     
-Throwables.propagate(e
+if (HttpStatusCode.UNAUTHORIZED.is(e.getStatusCode())) %7B%0A                //TODO We should change this interface to allow returning a response as well%0A                //     as a user. It would be nice to bubble up the fact that a 401 response%0A                //     was received from an AccessTokenChecker. In the meantime, we'll log%0A                //     this.%0A                log.info(%22Received a 401 response from Google: %7B%7D%22, e.getDetails()
 );%0A 
@@ -2313,19 +2313,177 @@
     
+    
 return 
-null
+Maybe.%3CUserRef%3Enothing();%0A            %7D%0A            throw Throwables.propagate(e);%0A        %7D catch (IOException e) %7B%0A            throw Throwables.propagate(e)
 ;%0A  
@@ -2486,21 +2486,22 @@
 ;%0A        %7D%0A
+%0A
     %7D%0A%0A%7D%0A

Improve error handling of invalid OAuth token