// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dev.cobalt.account;

import static android.Manifest.permission.GET_ACCOUNTS;
import static dev.cobalt.util.Log.TAG;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.OnAccountsUpdateListener;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.widget.Toast;
import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableAuthException;
import com.google.android.gms.common.AccountPicker;
import dev.cobalt.coat.R;
import dev.cobalt.util.Holder;
import dev.cobalt.util.Log;
import dev.cobalt.util.UsedByNative;
import java.io.IOException;

/**
 * Java side implementation for starboard::android::shared::cobalt::AndroidUserAuthorizer.
 *
 * This implements the following business logic:
 * First run...
 * - if there are no accounts, just be be signed-out
 * - if there is one account, sign-in without any UI
 * - if there are more than one accounts, prompt to choose account
 * Subsequent runs...
 * - sign-in to the same account last used to sign-in
 * - if previously signed-out stay signed-out
 * When user clicks 'sign-in' in the UI...
 * - if there are no accounts, allow user to add an account
 * - if there is one account, sign-in without any UI
 * - if there are more than one accounts, prompt to choose account
 * If the last signed-in account is deleted...
 * - kill the app if stopped in the background to prompt next time it starts
 * - at the next app start, show a toast that the account isn't available
 * - if there are no accounts left, just be be signed-out
 * - if there are one or more accounts left, prompt to choose account
 */
public class UserAuthorizerImpl implements OnAccountsUpdateListener, UserAuthorizer {

  /** Pseudo account indicating the user chose to be signed-out. */
  public static final Account SIGNED_OUT_ACCOUNT = new Account("-", "-");

  /** Pseudo account indicating a saved account no longer exists. */
  private static final Account MISSING_ACCOUNT = new Account("!", "!");

  /** Foreshortened expiry of Google OAuth token, which typically lasts 1 hour. */
  private static final long DEFAULT_EXPIRY_SECONDS = 5 * 60;

  private static final String GOOGLE_ACCOUNT_TYPE = "com.google";
  private static final String[] OAUTH_SCOPES = {
      "https://www.googleapis.com/auth/youtube"
  };

  private static final String SHARED_PREFS_NAME = "user_auth";
  private static final String ACCOUNT_NAME_PREF_KEY = "signed_in_account";

  /** The thread on which the current request is running, or null if none. */
  private volatile Thread requestThread;

  private final Context appContext;
  private final Holder<Activity> activityHolder;
  private final Runnable stopRequester;
  private final Handler mainHandler;

  private Account currentAccount = null;
  private AccessToken currentToken = null;

  // Result from the account picker UI lands here.
  private String chosenAccountName;

  private volatile boolean waitingForPermission;
  private volatile boolean permissionGranted;

  public UserAuthorizerImpl(
      Context appContext, Holder<Activity> activityHolder, Runnable stopRequester) {
    this.appContext = appContext;
    this.activityHolder = activityHolder;
    this.stopRequester = stopRequester;
    this.mainHandler = new Handler(Looper.getMainLooper());
    addOnAccountsUpdatedListener(this);
  }

  @Override
  public void shutdown() {
    removeOnAccountsUpdatedListener(this);
  }

  @Override
  @SuppressWarnings("unused")
  @UsedByNative
  public void interrupt() {
    Thread t = requestThread;
    if (t != null) {
      t.interrupt();
    }
  }

  @Override
  @SuppressWarnings("unused")
  @UsedByNative
  public AccessToken authorizeUser() {
    ensureBackgroundThread();
    requestThread = Thread.currentThread();
    // Let the user choose an account, or add one if there are none to choose.
    // However, if there's only one account just choose it without any prompt.
    currentAccount = autoSelectOrAddAccount();
    writeAccountPref(currentAccount);
    AccessToken accessToken = refreshCurrentToken();
    requestThread = null;
    return accessToken;
  }

  @Override
  @SuppressWarnings("unused")
  @UsedByNative
  public boolean deauthorizeUser() {
    ensureBackgroundThread();
    requestThread = Thread.currentThread();
    currentAccount = SIGNED_OUT_ACCOUNT;
    writeAccountPref(currentAccount);
    clearCurrentToken();
    requestThread = null;
    return true;
  }

  @Override
  @SuppressWarnings("unused")
  @UsedByNative
  public AccessToken refreshAuthorization() {
    ensureBackgroundThread();
    requestThread = Thread.currentThread();

    // If we haven't yet determined which account to use, check preferences for a saved account.
    if (currentAccount == null) {
      Account savedAccount = readAccountPref();
      if (savedAccount == null) {
        // No saved account, so this is the first ever run of the app.
        currentAccount = autoSelectAccount();
      } else if (savedAccount.equals(MISSING_ACCOUNT)) {
        // The saved account got deleted.
        currentAccount = forceSelectAccount();
      } else {
        // Use the saved account.
        currentAccount = savedAccount;
      }
      writeAccountPref(currentAccount);
    }

    AccessToken accessToken = refreshCurrentToken();
    requestThread = null;
    return accessToken;
  }

  private static void ensureBackgroundThread() {
    if (Looper.myLooper() == Looper.getMainLooper()) {
      throw new UnsupportedOperationException("UserAuthorizer can't be called on main thread");
    }
  }

  private void showToast(int resId, Object... formatArgs) {
    final String msg = appContext.getResources().getString(resId, formatArgs);
    mainHandler.post(new Runnable() {
      @Override
      public void run() {
        Toast.makeText(appContext, msg, Toast.LENGTH_LONG).show();
      }
    });
  }

  private Account readAccountPref() {
    String savedAccountName = loadSignedInAccountName();
    if (TextUtils.isEmpty(savedAccountName)) {
      return null;
    } else if (savedAccountName.equals(SIGNED_OUT_ACCOUNT.name)) {
      // Don't request permissions or look for a device account if we were signed-out.
      return SIGNED_OUT_ACCOUNT;
    } else if (!checkPermission()) {
      // We won't be able to get the account without permission, so warn the user and be signed-out.
      showToast(R.string.starboard_missing_account, savedAccountName);
      return SIGNED_OUT_ACCOUNT;
    } else {
      // Find the saved account name among all accounts on the device.
      for (Account account : getAccounts()) {
        if (account.name.equals(savedAccountName)) {
          return account;
        }
      }
      showToast(R.string.starboard_missing_account, savedAccountName);
      return MISSING_ACCOUNT;
    }
  }

  private void writeAccountPref(Account account) {
    if (account == null) {
      return;
    }
    // Always write the account name, even if it's the signed-out pseudo account.
    saveSignedInAccountName(account.name);
  }

  private void clearCurrentToken() {
    if (currentToken != null) {
      clearToken(currentToken.getTokenValue());
      currentToken = null;
    }
  }

  private AccessToken refreshCurrentToken() {
    clearCurrentToken();
    if (currentAccount == null || SIGNED_OUT_ACCOUNT.equals(currentAccount)) {
      return null;
    }
    String tokenValue = getToken(currentAccount);
    if (tokenValue == null) {
      showToast(R.string.starboard_account_auth_error);
      tokenValue = "";
    }
    // TODO: Get the token details and use the actual expiry.
    long expiry = System.currentTimeMillis() / 1000 + DEFAULT_EXPIRY_SECONDS;
    currentToken = new AccessToken(tokenValue, expiry);
    return currentToken;
  }

  /**
   * Prompts the user to select an account, or to add an account if there are none. The prompt is
   * skipped if there is exactly one account to choose from.
   */
  private Account autoSelectOrAddAccount() {
    if (!checkPermission()) {
      return SIGNED_OUT_ACCOUNT;
    }
    Account[] accounts = getAccounts();
    if (accounts.length == 1) {
      return accounts[0];
    }
    return selectOrAddAccount();
  }

  /**
   * Prompts the user to select an account. The prompt is skipped if there are zero or one accounts
   * to choose from.
   */
  private Account autoSelectAccount() {
    if (!checkPermission()) {
      return SIGNED_OUT_ACCOUNT;
    }
    Account[] accounts = getAccounts();
    if (accounts.length == 0) {
      return SIGNED_OUT_ACCOUNT;
    } else if (accounts.length == 1) {
      return accounts[0];
    }
    return selectOrAddAccount();
  }

  /**
   * Prompts the user to select an account, even if there's only one to choose from. The prompt is
   * skipped if there are zero accounts to choose from.
   */
  private Account forceSelectAccount() {
    // We don't check permissions before calling selectOrAddAccount() because if the account is
    // missing, readAccountPref() must have just checked, and we don't want to show permission
    // prompt or rationale to the user twice.
    Account[] accounts = getAccounts();
    if (accounts.length == 0) {
      return SIGNED_OUT_ACCOUNT;
    }
    return selectOrAddAccount();
  }

  /**
   * Prompts the user to select an account, even if there's only one to choose from. If there are
   * zero accounts to choose from, the user is prompted to add one.
   *
   * The caller should ensure permissions are granted before calling this method to avoid showing
   * a picker with accounts that we can't access.
   */
  private Account selectOrAddAccount() {
    String accountName = showAccountPicker();
    // If user cancelled the picker stay signed-out.
    if (TextUtils.isEmpty(accountName)) {
      return SIGNED_OUT_ACCOUNT;
    }
    // Get the accounts after the picker in case one was added in the account picker.
    for (Account account : getAccounts()) {
      if (account.name.equals(accountName)) {
        return account;
      }
    }
    // This shouldn't happen, but if it does let the user know we're still signed-out.
    Log.e(TAG, "Selected account is missing");
    showToast(R.string.starboard_missing_account, accountName);
    return SIGNED_OUT_ACCOUNT;
  }

  private synchronized String showAccountPicker() {
    Activity activity = activityHolder.get();
    Intent chooseAccountIntent = newChooseAccountIntent(currentAccount);
    if (activity == null || chooseAccountIntent == null) {
      return "";
    }
    chosenAccountName = null;
    activity.startActivityForResult(chooseAccountIntent, R.id.rc_choose_account);

    // Block until the account picker activity returns its result.
    while (chosenAccountName == null) {
      try {
        wait();
      } catch (InterruptedException e) {
        Log.e(TAG, "Account picker interrupted");
        // Return empty string, as if the picker was cancelled.
        return "";
      }
    }
    return chosenAccountName;
  }

  @Override
  public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == R.id.rc_choose_account) {
      String accountName = null;
      if (resultCode == Activity.RESULT_OK) {
        accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
      } else if (resultCode != Activity.RESULT_CANCELED) {
        Log.e(TAG, "Account picker error " + resultCode);
        showToast(R.string.starboard_account_picker_error);
      }

      // Notify showAccountPicker() which account was chosen.
      synchronized (this) {
        // Return empty string if the picker is cancelled or there's an unexpected result.
        chosenAccountName = (accountName == null) ? "" : accountName;
        notifyAll();
      }
    }
  }

  @Override
  public void onAccountsUpdated(Account[] unused) {
    if (currentAccount == null || SIGNED_OUT_ACCOUNT.equals(currentAccount)) {
      // We're not signed-in; the update doesn't affect us.
      return;
    }
    // Call getAccounts() since the param may not match the accounts we can access.
    for (Account account : getAccounts()) {
      if (account.name.equals(currentAccount.name)) {
        // The current account is still there; the update doesn't affect us.
        return;
      }
    }
    // The current account is gone; leave the app so we prompt for sign-in next time.
    // This should only happen while stopped in the background since we don't delete accounts.
    stopRequester.run();
  }

  /**
   * Calls framework AccountManager.addOnAccountsUpdatedListener().
   */
  private void addOnAccountsUpdatedListener(OnAccountsUpdateListener listener) {
    AccountManager.get(appContext).addOnAccountsUpdatedListener(listener, null, false);
  }

  /**
   * Calls framework AccountManager.removeOnAccountsUpdatedListener().
   */
  private void removeOnAccountsUpdatedListener(OnAccountsUpdateListener listener) {
    AccountManager.get(appContext).removeOnAccountsUpdatedListener(listener);
  }

  /**
   * Calls framework AccountManager.getAccountsByType() for Google accounts.
   */
  private Account[] getAccounts() {
    return AccountManager.get(appContext).getAccountsByType(GOOGLE_ACCOUNT_TYPE);
  }

  /**
   * Calls GMS AccountPicker.newChooseAccountIntent().
   *
   * Returns an Intent that when started will always show the account picker even if there's just
   * one account on the device. If there are no accounts on the device it shows the UI to add one.
   */
  private Intent newChooseAccountIntent(Account defaultAccount) {
    String[] allowableAccountTypes = {GOOGLE_ACCOUNT_TYPE};
    return AccountPicker.newChooseAccountIntent(
        defaultAccount, null, allowableAccountTypes, true, null, null, null, null);
  }

  /**
   * Calls GMS GoogleAuthUtil.getToken(), without throwing any exceptions.
   *
   * Returns an empty string if no token is available for the account.
   * Returns null if there was an error getting the token.
   */
  private String getToken(Account account) {
    String joinedScopes = "oauth2:" + TextUtils.join(" ", OAUTH_SCOPES);
    try {
      return GoogleAuthUtil.getToken(appContext, account, joinedScopes);
    } catch (UserRecoverableAuthException e) {
        Log.w(TAG, "Recoverable error getting OAuth token", e);
        Intent intent = e.getIntent();
        Activity activity = activityHolder.get();
        if (intent != null && activity != null) {
          activity.startActivity(intent);
        } else {
          Log.e(TAG, "Failed to recover OAuth token", e);
        }
        return null;

    } catch (IOException | GoogleAuthException e) {
      Log.e(TAG, "Error getting auth token", e);
      return null;
    }
  }

  /**
   * Calls GMS GoogleAuthUtil.clearToken(), without throwing any exceptions.
   */
  private void clearToken(String tokenValue) {
    try {
      GoogleAuthUtil.clearToken(appContext, tokenValue);
    } catch (GoogleAuthException | IOException e) {
      Log.e(TAG, "Error clearing auth token", e);
    }
  }

  /**
   * Checks whether the app has necessary permissions, asking for them if needed.
   *
   * This blocks until permissions are granted/declined, and should not be called on the UI thread.
   *
   * Returns true if permissions are granted.
   */
  private synchronized boolean checkPermission() {
    if (ContextCompat.checkSelfPermission(appContext, GET_ACCOUNTS)
        == PackageManager.PERMISSION_GRANTED) {
      return true;
    }

    final Activity activity = activityHolder.get();
    if (activity == null) {
      return false;
    }

    // Check if we have previously been denied permission.
    if (ActivityCompat.shouldShowRequestPermissionRationale(activity, GET_ACCOUNTS)) {
      activity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
          Toast.makeText(activity, R.string.starboard_accounts_permission, Toast.LENGTH_LONG)
              .show();
        }
      });
      return false;
    }

    // Request permission.
    waitingForPermission = true;
    permissionGranted = false;
    ActivityCompat.requestPermissions(
        activity, new String[]{GET_ACCOUNTS}, R.id.rc_get_accounts_permission);
    try {
      while (waitingForPermission) {
        wait();
      }
    } catch (InterruptedException e) {
      return false;
    }
    return permissionGranted;
  }

  /**
   * Callback pass-thru from the Activity with the result from requesting permissions.
   */
  @Override
  public void onRequestPermissionsResult(
      int requestCode, String[] permissions, int[] grantResults) {
    if (requestCode == R.id.rc_get_accounts_permission) {
      synchronized (this) {
        permissionGranted = grantResults.length > 0
            && grantResults[0] == PackageManager.PERMISSION_GRANTED;
        waitingForPermission = false;
        notifyAll();
      }
    }
  }

  /**
   * Remember the name of the signed-in account.
   */
  private void saveSignedInAccountName(String accountName) {
    getPreferences().edit().putString(ACCOUNT_NAME_PREF_KEY, accountName).commit();
  }

  /**
   * Returns the remembered name of the signed-in account.
   */
  private String loadSignedInAccountName() {
    return getPreferences().getString(ACCOUNT_NAME_PREF_KEY, "");
  }

  private SharedPreferences getPreferences() {
    return appContext.getSharedPreferences(SHARED_PREFS_NAME, 0);
  }
}
