// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "FirebaseAuthPlugin.h"
#import "UserAgent.h"

#import "Firebase/Firebase.h"

static NSString *getFlutterErrorCode(NSError *error) {
  NSString *code = [error userInfo][FIRAuthErrorUserInfoNameKey];
  if (code != nil) {
    return code;
  }
  return [NSString stringWithFormat:@"ERROR_%d", (int)error.code];
}

NSDictionary *toDictionary(id<FIRUserInfo> userInfo) {
  return @{
    @"providerId" : userInfo.providerID,
    @"displayName" : userInfo.displayName ?: [NSNull null],
    @"uid" : userInfo.uid ?: [NSNull null],
    @"photoUrl" : userInfo.photoURL.absoluteString ?: [NSNull null],
    @"email" : userInfo.email ?: [NSNull null],
    @"phoneNumber" : userInfo.phoneNumber ?: [NSNull null],
  };
}

@interface FLTFirebaseAuthPlugin ()
@property(nonatomic, retain) NSMutableDictionary *authStateChangeListeners;
@property(nonatomic, retain) FlutterMethodChannel *channel;
@end

@implementation FLTFirebaseAuthPlugin

// Handles are ints used as indexes into the NSMutableDictionary of active observers
int nextHandle = 0;

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
  FlutterMethodChannel *channel =
      [FlutterMethodChannel methodChannelWithName:@"plugins.flutter.io/firebase_auth"
                                  binaryMessenger:[registrar messenger]];
  FLTFirebaseAuthPlugin *instance = [[FLTFirebaseAuthPlugin alloc] init];
  instance.channel = channel;
  instance.authStateChangeListeners = [[NSMutableDictionary alloc] init];
  [registrar addApplicationDelegate:instance];
  [registrar addMethodCallDelegate:instance channel:channel];

  SEL sel = NSSelectorFromString(@"registerLibrary:withVersion:");
  if ([FIRApp respondsToSelector:sel]) {
    [FIRApp performSelector:sel withObject:LIBRARY_NAME withObject:LIBRARY_VERSION];
  }
}

- (instancetype)init {
  self = [super init];
  if (self) {
    if (![FIRApp appNamed:@"__FIRAPP_DEFAULT"]) {
      NSLog(@"Configuring the default Firebase app...");
      [FIRApp configure];
      NSLog(@"Configured the default Firebase app %@.", [FIRApp defaultApp].name);
    }
  }
  return self;
}

- (FIRAuth *_Nullable)getAuth:(NSDictionary *)args {
  NSString *appName = [args objectForKey:@"app"];
  return [FIRAuth authWithApp:[FIRApp appNamed:appName]];
}

- (bool)application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)notification
          fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
  if ([[FIRAuth auth] canHandleNotification:notification]) {
    completionHandler(UIBackgroundFetchResultNoData);
    return YES;
  }
  return NO;
}

- (void)application:(UIApplication *)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  [[FIRAuth auth] setAPNSToken:deviceToken type:FIRAuthAPNSTokenTypeProd];
}

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options {
  return [[FIRAuth auth] canHandleURL:url];
}

// TODO(jackson): We should use the renamed versions of the following methods
// when they are available in the Firebase SDK that this plugin is dependent on.
// * fetchSignInMethodsForEmail:completion:
// * reauthenticateAndRetrieveDataWithCredential:completion:
// * linkAndRetrieveDataWithCredential:completion:
// * signInAndRetrieveDataWithCredential:completion:
// See discussion at https://github.com/flutter/plugins/pull/1487
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
  if ([@"currentUser" isEqualToString:call.method]) {
    id __block listener = [[self getAuth:call.arguments]
        addAuthStateDidChangeListener:^(FIRAuth *_Nonnull auth, FIRUser *_Nullable user) {
          [self sendResult:result forUser:user error:nil];
          [auth removeAuthStateDidChangeListener:listener];
        }];
  } else if ([@"signInAnonymously" isEqualToString:call.method]) {
    [[self getAuth:call.arguments]
        signInAnonymouslyWithCompletion:^(FIRAuthDataResult *authResult, NSError *error) {
          [self sendResult:result forAuthDataResult:authResult error:error];
        }];
  } else if ([@"signInWithCredential" isEqualToString:call.method]) {
    [[self getAuth:call.arguments]
        signInAndRetrieveDataWithCredential:[self getCredential:call.arguments]
                                 completion:^(FIRAuthDataResult *authResult, NSError *error) {
                                   [self sendResult:result
                                       forAuthDataResult:authResult
                                                   error:error];
                                 }];
  } else if ([@"createUserWithEmailAndPassword" isEqualToString:call.method]) {
    NSString *email = call.arguments[@"email"];
    NSString *password = call.arguments[@"password"];
    [[self getAuth:call.arguments]
        createUserWithEmail:email
                   password:password
                 completion:^(FIRAuthDataResult *authResult, NSError *error) {
                   [self sendResult:result forAuthDataResult:authResult error:error];
                 }];
  } else if ([@"fetchSignInMethodsForEmail" isEqualToString:call.method]) {
    NSString *email = call.arguments[@"email"];
    [[self getAuth:call.arguments]
        fetchProvidersForEmail:email
                    completion:^(NSArray<NSString *> *providers, NSError *error) {
                      [self sendResult:result forObject:providers error:error];
                    }];
  } else if ([@"sendEmailVerification" isEqualToString:call.method]) {
    [[self getAuth:call.arguments].currentUser
        sendEmailVerificationWithCompletion:^(NSError *_Nullable error) {
          [self sendResult:result forObject:nil error:error];
        }];
  } else if ([@"reload" isEqualToString:call.method]) {
    [[self getAuth:call.arguments].currentUser reloadWithCompletion:^(NSError *_Nullable error) {
      [self sendResult:result forObject:nil error:error];
    }];
  } else if ([@"delete" isEqualToString:call.method]) {
    [[self getAuth:call.arguments].currentUser deleteWithCompletion:^(NSError *_Nullable error) {
      [self sendResult:result forObject:nil error:error];
    }];
  } else if ([@"sendPasswordResetEmail" isEqualToString:call.method]) {
    NSString *email = call.arguments[@"email"];
    [[self getAuth:call.arguments] sendPasswordResetWithEmail:email
                                                   completion:^(NSError *error) {
                                                     [self sendResult:result
                                                            forObject:nil
                                                                error:error];
                                                   }];
  } else if ([@"sendLinkToEmail" isEqualToString:call.method]) {
    NSString *email = call.arguments[@"email"];
    FIRActionCodeSettings *actionCodeSettings = [FIRActionCodeSettings new];
    actionCodeSettings.URL = [NSURL URLWithString:call.arguments[@"url"]];
    actionCodeSettings.handleCodeInApp = call.arguments[@"handleCodeInApp"];
    [actionCodeSettings setIOSBundleID:call.arguments[@"iOSBundleID"]];
    [actionCodeSettings setAndroidPackageName:call.arguments[@"androidPackageName"]
                        installIfNotAvailable:call.arguments[@"androidInstallIfNotAvailable"]
                               minimumVersion:call.arguments[@"androidMinimumVersion"]];
    [[self getAuth:call.arguments] sendSignInLinkToEmail:email
                                      actionCodeSettings:actionCodeSettings
                                              completion:^(NSError *_Nullable error) {
                                                [self sendResult:result forObject:nil error:error];
                                              }];
  } else if ([@"isSignInWithEmailLink" isEqualToString:call.method]) {
    NSString *link = call.arguments[@"link"];
    BOOL status = [[self getAuth:call.arguments] isSignInWithEmailLink:link];
    [self sendResult:result forObject:[NSNumber numberWithBool:status] error:nil];
  } else if ([@"signInWithEmailAndLink" isEqualToString:call.method]) {
    NSString *email = call.arguments[@"email"];
    NSString *link = call.arguments[@"link"];
    [[self getAuth:call.arguments]
        signInWithEmail:email
                   link:link
             completion:^(FIRAuthDataResult *_Nullable authResult, NSError *_Nullable error) {
               [self sendResult:result forAuthDataResult:authResult error:error];
             }];
  } else if ([@"signInWithEmailAndPassword" isEqualToString:call.method]) {
    NSString *email = call.arguments[@"email"];
    NSString *password = call.arguments[@"password"];
    [[self getAuth:call.arguments]
        signInWithEmail:email
               password:password
             completion:^(FIRAuthDataResult *authResult, NSError *error) {
               [self sendResult:result forAuthDataResult:authResult error:error];
             }];
  } else if ([@"signOut" isEqualToString:call.method]) {
    NSError *signOutError;
    BOOL status = [[self getAuth:call.arguments] signOut:&signOutError];
    if (!status) {
      NSLog(@"Error signing out: %@", signOutError);
      [self sendResult:result forObject:nil error:signOutError];
    } else {
      [self sendResult:result forObject:nil error:nil];
    }
  } else if ([@"getIdToken" isEqualToString:call.method]) {
    NSDictionary *args = call.arguments;
    BOOL refresh = [args objectForKey:@"refresh"];
    [[self getAuth:call.arguments].currentUser
        getIDTokenResultForcingRefresh:refresh
                            completion:^(FIRAuthTokenResult *_Nullable tokenResult,
                                         NSError *_Nullable error) {
                              NSMutableDictionary *tokenData = nil;
                              if (tokenResult != nil) {
                                long expirationTimestamp =
                                    [tokenResult.expirationDate timeIntervalSince1970];
                                long authTimestamp = [tokenResult.authDate timeIntervalSince1970];
                                long issuedAtTimestamp =
                                    [tokenResult.issuedAtDate timeIntervalSince1970];

                                tokenData = [[NSMutableDictionary alloc] initWithDictionary:@{
                                  @"token" : tokenResult.token,
                                  @"expirationTimestamp" :
                                      [NSNumber numberWithInt:expirationTimestamp],
                                  @"authTimestamp" : [NSNumber numberWithInt:authTimestamp],
                                  @"issuedAtTimestamp" : [NSNumber numberWithInt:issuedAtTimestamp],
                                  @"claims" : tokenResult.claims,
                                }];

                                if (tokenResult.signInProvider != nil) {
                                  tokenData[@"signInProvider"] = tokenResult.signInProvider;
                                }
                              }

                              [self sendResult:result forObject:tokenData error:error];
                            }];
  } else if ([@"reauthenticateWithCredential" isEqualToString:call.method]) {
    [[self getAuth:call.arguments].currentUser
        reauthenticateAndRetrieveDataWithCredential:[self getCredential:call.arguments]
                                         completion:^(FIRAuthDataResult *r,
                                                      NSError *_Nullable error) {
                                           [self sendResult:result forObject:nil error:error];
                                         }];
  } else if ([@"linkWithCredential" isEqualToString:call.method]) {
    [[self getAuth:call.arguments].currentUser
        linkAndRetrieveDataWithCredential:[self getCredential:call.arguments]
                               completion:^(FIRAuthDataResult *authResult, NSError *error) {
                                 [self sendResult:result forAuthDataResult:authResult error:error];
                               }];
  } else if ([@"unlinkFromProvider" isEqualToString:call.method]) {
    NSString *provider = call.arguments[@"provider"];
    [[self getAuth:call.arguments].currentUser
        unlinkFromProvider:provider
                completion:^(FIRUser *_Nullable user, NSError *_Nullable error) {
                  [self sendResult:result forUser:user error:error];
                }];
  } else if ([@"updateEmail" isEqualToString:call.method]) {
    NSString *email = call.arguments[@"email"];
    [[self getAuth:call.arguments].currentUser updateEmail:email
                                                completion:^(NSError *error) {
                                                  [self sendResult:result
                                                         forObject:nil
                                                             error:error];
                                                }];
  } else if ([@"updatePhoneNumberCredential" isEqualToString:call.method]) {
    FIRPhoneAuthCredential *credential =
        (FIRPhoneAuthCredential *)[self getCredential:call.arguments];
    [[self getAuth:call.arguments].currentUser
        updatePhoneNumberCredential:credential
                         completion:^(NSError *_Nullable error) {
                           [self sendResult:result forObject:nil error:error];
                         }];
  } else if ([@"updatePassword" isEqualToString:call.method]) {
    NSString *password = call.arguments[@"password"];
    [[self getAuth:call.arguments].currentUser updatePassword:password
                                                   completion:^(NSError *error) {
                                                     [self sendResult:result
                                                            forObject:nil
                                                                error:error];
                                                   }];
  } else if ([@"updateProfile" isEqualToString:call.method]) {
    FIRUserProfileChangeRequest *changeRequest =
        [[self getAuth:call.arguments].currentUser profileChangeRequest];
    if (call.arguments[@"displayName"]) {
      changeRequest.displayName = call.arguments[@"displayName"];
    }
    if (call.arguments[@"photoUrl"]) {
      changeRequest.photoURL = [NSURL URLWithString:call.arguments[@"photoUrl"]];
    }
    [changeRequest commitChangesWithCompletion:^(NSError *error) {
      [self sendResult:result forObject:nil error:error];
    }];
  } else if ([@"signInWithCustomToken" isEqualToString:call.method]) {
    NSString *token = call.arguments[@"token"];
    [[self getAuth:call.arguments]
        signInWithCustomToken:token
                   completion:^(FIRAuthDataResult *authResult, NSError *error) {
                     [self sendResult:result forAuthDataResult:authResult error:error];
                   }];

  } else if ([@"startListeningAuthState" isEqualToString:call.method]) {
    NSNumber *identifier = [NSNumber numberWithInteger:nextHandle++];

    FIRAuthStateDidChangeListenerHandle listener = [[self getAuth:call.arguments]
        addAuthStateDidChangeListener:^(FIRAuth *_Nonnull auth, FIRUser *_Nullable user) {
          NSMutableDictionary *response = [[NSMutableDictionary alloc] init];
          response[@"id"] = identifier;
          if (user) {
            response[@"user"] = [self dictionaryFromUser:user];
          }
          [self.channel invokeMethod:@"onAuthStateChanged" arguments:response];
        }];
    [self.authStateChangeListeners setObject:listener forKey:identifier];
    result(identifier);
  } else if ([@"stopListeningAuthState" isEqualToString:call.method]) {
    NSNumber *identifier =
        [NSNumber numberWithInteger:[call.arguments[@"id"] unsignedIntegerValue]];

    FIRAuthStateDidChangeListenerHandle listener = self.authStateChangeListeners[identifier];
    if (listener) {
      [[self getAuth:call.arguments]
          removeAuthStateDidChangeListener:self.authStateChangeListeners];
      [self.authStateChangeListeners removeObjectForKey:identifier];
      result(nil);
    } else {
      result([FlutterError
          errorWithCode:@"ERROR_LISTENER_NOT_FOUND"
                message:[NSString stringWithFormat:@"Listener with identifier '%d' not found.",
                                                   identifier.intValue]
                details:nil]);
    }
  } else if ([@"verifyPhoneNumber" isEqualToString:call.method]) {
    NSString *phoneNumber = call.arguments[@"phoneNumber"];
    NSNumber *handle = call.arguments[@"handle"];
    [[FIRPhoneAuthProvider provider]
        verifyPhoneNumber:phoneNumber
               UIDelegate:nil
               completion:^(NSString *verificationID, NSError *error) {
                 if (error) {
                   [self.channel invokeMethod:@"phoneVerificationFailed"
                                    arguments:@{
                                      @"exception" : [self mapVerifyPhoneError:error],
                                      @"handle" : handle
                                    }];
                 } else {
                   [self.channel
                       invokeMethod:@"phoneCodeSent"
                          arguments:@{@"verificationId" : verificationID, @"handle" : handle}];
                 }
               }];
    result(nil);
  } else if ([@"signInWithPhoneNumber" isEqualToString:call.method]) {
    NSString *verificationId = call.arguments[@"verificationId"];
    NSString *smsCode = call.arguments[@"smsCode"];

    FIRPhoneAuthCredential *credential =
        [[FIRPhoneAuthProvider provider] credentialWithVerificationID:verificationId
                                                     verificationCode:smsCode];
    [[self getAuth:call.arguments]
        signInAndRetrieveDataWithCredential:credential
                                 completion:^(FIRAuthDataResult *authResult,
                                              NSError *_Nullable error) {
                                   [self sendResult:result
                                       forAuthDataResult:authResult
                                                   error:error];
                                 }];
  } else if ([@"setLanguageCode" isEqualToString:call.method]) {
    NSString *language = call.arguments[@"language"];
    [[self getAuth:call.arguments] setLanguageCode:language];
    [self sendResult:result forObject:nil error:nil];
  } else {
    result(FlutterMethodNotImplemented);
  }
}

- (NSMutableDictionary *)dictionaryFromUser:(FIRUser *)user {
  NSMutableArray<NSDictionary<NSString *, NSString *> *> *providerData =
      [NSMutableArray arrayWithCapacity:user.providerData.count];
  for (id<FIRUserInfo> userInfo in user.providerData) {
    [providerData addObject:toDictionary(userInfo)];
  }

  long creationDate = [user.metadata.creationDate timeIntervalSince1970] * 1000;
  long lastSignInDate = [user.metadata.lastSignInDate timeIntervalSince1970] * 1000;

  NSMutableDictionary *userData = [toDictionary(user) mutableCopy];
  userData[@"creationTimestamp"] = [NSNumber numberWithLong:creationDate];
  userData[@"lastSignInTimestamp"] = [NSNumber numberWithLong:lastSignInDate];
  userData[@"isAnonymous"] = [NSNumber numberWithBool:user.isAnonymous];
  userData[@"isEmailVerified"] = [NSNumber numberWithBool:user.isEmailVerified];
  userData[@"providerData"] = providerData;
  return userData;
}
#pragma clang diagnostic pop

- (void)sendResult:(FlutterResult)result
    forAuthDataResult:(FIRAuthDataResult *)authResult
                error:(NSError *)error {
  FIRUser *user = authResult.user;
  FIRAdditionalUserInfo *additionalUserInfo = authResult.additionalUserInfo;
  [self sendResult:result
         forObject:@{
           @"user" : (user != nil ? [self dictionaryFromUser:user] : [NSNull null]),
           @"additionalUserInfo" : additionalUserInfo ? @{
             @"isNewUser" : [NSNumber numberWithBool:additionalUserInfo.isNewUser],
             @"username" : additionalUserInfo.username ?: [NSNull null],
             @"providerId" : additionalUserInfo.providerID ?: [NSNull null],
             @"profile" : additionalUserInfo.profile ?: [NSNull null],
           }
                                                      : [NSNull null],
         }
             error:error];
}

- (void)sendResult:(FlutterResult)result forUser:(FIRUser *)user error:(NSError *)error {
  [self sendResult:result
         forObject:(user != nil ? [self dictionaryFromUser:user] : nil)
             error:error];
}

- (void)sendResult:(FlutterResult)result forObject:(NSObject *)object error:(NSError *)error {
  if (error != nil) {
    result([FlutterError errorWithCode:getFlutterErrorCode(error)
                               message:error.localizedDescription
                               details:nil]);
  } else if (object == nil) {
    result(nil);
  } else {
    result(object);
  }
}

- (id)mapVerifyPhoneError:(NSError *)error {
  NSString *errorCode = @"verifyPhoneNumberError";

  if (error.code == FIRAuthErrorCodeCaptchaCheckFailed) {
    errorCode = @"captchaCheckFailed";
  } else if (error.code == FIRAuthErrorCodeQuotaExceeded) {
    errorCode = @"quotaExceeded";
  } else if (error.code == FIRAuthErrorCodeInvalidPhoneNumber) {
    errorCode = @"invalidPhoneNumber";
  } else if (error.code == FIRAuthErrorCodeMissingPhoneNumber) {
    errorCode = @"missingPhoneNumber";
  }
  return @{@"code" : errorCode, @"message" : error.localizedDescription};
}

- (FIRAuthCredential *)getCredential:(NSDictionary *)arguments {
  NSString *provider = arguments[@"provider"];
  NSDictionary *data = arguments[@"data"];
  FIRAuthCredential *credential;
  if ([FIREmailAuthProviderID isEqualToString:provider]) {
    NSString *email = data[@"email"];
    if ([data objectForKey:@"password"]) {
      NSString *password = data[@"password"];
      credential = [FIREmailAuthProvider credentialWithEmail:email password:password];
    } else {
      NSString *link = data[@"link"];
      credential = [FIREmailAuthProvider credentialWithEmail:email link:link];
    }
  } else if ([FIRGoogleAuthProviderID isEqualToString:provider]) {
    NSString *idToken = data[@"idToken"];
    NSString *accessToken = data[@"accessToken"];
    credential = [FIRGoogleAuthProvider credentialWithIDToken:idToken accessToken:accessToken];
  } else if ([FIRFacebookAuthProviderID isEqualToString:provider]) {
    NSString *accessToken = data[@"accessToken"];
    credential = [FIRFacebookAuthProvider credentialWithAccessToken:accessToken];
  } else if ([FIRTwitterAuthProviderID isEqualToString:provider]) {
    NSString *authToken = data[@"authToken"];
    NSString *authTokenSecret = data[@"authTokenSecret"];
    credential = [FIRTwitterAuthProvider credentialWithToken:authToken secret:authTokenSecret];
  } else if ([FIRGitHubAuthProviderID isEqualToString:provider]) {
    NSString *token = data[@"token"];
    credential = [FIRGitHubAuthProvider credentialWithToken:token];
  } else if ([FIRPhoneAuthProviderID isEqualToString:provider]) {
    NSString *verificationId = data[@"verificationId"];
    NSString *smsCode = data[@"smsCode"];
    credential = [[FIRPhoneAuthProvider providerWithAuth:[self getAuth:arguments]]
        credentialWithVerificationID:verificationId
                    verificationCode:smsCode];
  } else {
    NSLog(@"Support for an auth provider with identifier '%@' is not implemented.", provider);
  }
  return credential;
}
@end
