package com.springsource.greenhouse.settings;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;

import org.springframework.dao.DuplicateKeyException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth.consumer.token.OAuthConsumerToken;
import org.springframework.security.oauth.consumer.token.OAuthConsumerTokenServicesFactory;
import org.springframework.security.oauth.extras.OAuthConsumerTokenServicesHelper;
import org.springframework.social.twitter.TwitterOperations;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.flash.FlashMap;

import com.springsource.greenhouse.account.Account;
import com.springsource.greenhouse.account.AccountRepository;
import com.springsource.greenhouse.utils.MemberUtils;
import com.springsource.greenhouse.utils.SecurityUtils;

@Controller
@RequestMapping("/settings")
public class TwitterSettingsController {
	
	private OAuthConsumerTokenServicesHelper oauthHelper;

	private TwitterOperations twitterService;
	
	private JdbcTemplate jdbcTemplate;

	private final AccountRepository accountRepository;
	
	@Inject
	public TwitterSettingsController(OAuthConsumerTokenServicesFactory oauthTokenFactory, 
			TwitterOperations twitterService, JdbcTemplate jdbcTemplate, AccountRepository accountRepository) {
		this.accountRepository = accountRepository;
		this.oauthHelper = new OAuthConsumerTokenServicesHelper(oauthTokenFactory);
		this.jdbcTemplate = jdbcTemplate;
		this.twitterService = twitterService;
	}

	@RequestMapping(value="/twitter", method=RequestMethod.GET)
	public String connectView(Account account) {
		if (accountRepository.isConnected(account.getId(), "twitter")) {
			return "settings/twitterConnected";
		} else {
			return "settings/twitterConnect";
		}
	}

	// TODO - change this callback url to /twitter/authorize and simplify @RequestMapping values
	@RequestMapping("/twitter/authorize")
	public String authorize(HttpServletRequest request, Authentication authentication) {
		String oauthToken = request.getParameter("oauth_token");
		if (oauthToken != null && oauthToken.length() > 0) {
			OAuthConsumerToken accessToken = oauthHelper.getAccessToken("twitter", request, authentication);
			Account account = (Account) authentication.getPrincipal();
			makeTwitterScreenameGreenhouseUsername(accessToken, account);
			if (request.getParameter("tweetIt") != null) {
				// TODO should this be done asynchronously?
				tweetConnection(accessToken, request, account);
			}
			FlashMap.setSuccessMessage("Your Twitter account is now linked to your Greenhouse account!");
		}
		return "redirect:/settings/twitter";
	}

	@RequestMapping(value="/twitter", method=RequestMethod.DELETE)
	public String disconnectTwitter(Account account, HttpServletRequest request, Authentication authentication) {
		oauthHelper.removeToken("twitter", request, authentication);
		return "redirect:/settings/twitter";
	}

	// internal helpers
	private void tweetConnection(OAuthConsumerToken accessToken, HttpServletRequest request, Account account) {
		String message = "Linked with the Greenhouse at " + MemberUtils.assembleMemberProfileUrl(request, account);
		twitterService.updateStatus(accessToken, message);
	}

	private void makeTwitterScreenameGreenhouseUsername(OAuthConsumerToken accessToken, Account account) {
		String screenName = twitterService.getScreenName(accessToken);
		try {
			jdbcTemplate.update("update Member set username = ? where id = ?", screenName, account.getId());
			SecurityUtils.signin(account.newUsername(screenName));
		} catch (DuplicateKeyException e) {
			// TODO add an info message that gets displayed under the success message
		}
	}
	
}
@@ -1122,16 +1122,208 @@
 ler %7B%0A%09%0A
+%09private static final String TWITTER = %22twitter%22;%0A%09private static final String UPDATE_CONNECTED_ACCOUNT_ID = %0A%09%09%22update ConnectedAccount set accountId = ? where member = ? and provider = ?%22;%0A%0A
 %09private
@@ -2070,25 +2070,23 @@
 etId(), 
-%22twitter%22
+TWITTER
 )) %7B%0A%09%09%09
@@ -2569,33 +2569,31 @@
 AccessToken(
-%22twitter%22
+TWITTER
 , request, a
@@ -2677,69 +2677,233 @@
 %0A%09%09%09
-makeTwitterScreenameGreenhouseUsername(accessToken, account);
+%0A%09%09%09String screenName = twitterService.getScreenName(accessToken);%0A%09%09%09makeTwitterScreenameGreenhouseUsername(screenName, account);%0A%09%09%09jdbcTemplate.update(UPDATE_CONNECTED_ACCOUNT_ID, screenName, account.getId(), TWITTER);%0A%09%09%09
 %0A%09%09%09
@@ -3399,25 +3399,23 @@
 veToken(
-%22twitter%22
+TWITTER
 , reques
@@ -3831,123 +3831,45 @@
 ame(
-OAuthConsumerToken accessToken, Account account) %7B%0A%09%09String screenName = twitterService.getScreenName(accessToken);
+String screenName, Account account) %7B
 %0A%09%09t

Set connected account ID to Twitter screenname after connecting to Twitter.