/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */
import {Inject, Injectable} from '@angular/core';
import {Actions, Effect} from '@ngrx/effects';
import {Observable} from 'rxjs/Observable';
import {Action, Store} from '@ngrx/store';
import {of} from 'rxjs/observable/of';
import * as securityActions from '../security.actions';
import {AuthenticationService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/security/authn/authentication.service';
import {PermissionId} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/security/authz/permission-id.type';
import {FimsPermission} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/security/authz/fims-permission.model';
import {Permission} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/identity/domain/permission.model';
import {PermittableGroupIdMapper} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/security/authz/permittable-group-id-mapper';
import * as fromRoot from '../../index';
import {IdentityService} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/identity/identity.service';
import {Password} from '/home/pembe/Desktop/fineract-cn-web-app/src/app/sevices/identity/domain/password.model';

@Injectable()
export class SecurityApiEffects {

  @Effect()
  login$: Observable<Action> = this.actions$
    .ofType(securityActions.LOGIN)
    .map((action: securityActions.LoginAction) => action.payload)
    .mergeMap(payload =>
      this.authenticationService.login(payload.tenant, payload.username, payload.password)
        .map(authentication => Object.assign({}, {
          username: payload.username,
          tenant: payload.tenant,
          authentication: authentication
        }))
        .map(successPayload => new securityActions.LoginSuccessAction(successPayload))
        .catch((error) => of(new securityActions.LoginFailAction(error)))
    );

  @Effect()
  loadPermissions$: Observable<Action> = this.actions$
    .ofType(securityActions.LOGIN_SUCCESS)
    .map((action: securityActions.LoginSuccessAction) => action.payload)
    .mergeMap(payload =>
      this.fetchPermissions(payload.tenant, payload.username, payload.authentication.accessToken)
        .map(permissions => new securityActions.PermissionUpdateSuccessAction(permissions))
        .catch(error => of(new securityActions.PermissionUpdateFailAction(error)))
    );

  @Effect()
  startRefreshTokenTimer$: Observable<Action> = this.actions$
    .ofType(securityActions.LOGIN_SUCCESS)
    .map((action: securityActions.LoginSuccessAction) => action.payload)
    .map(payload => new Date(payload.authentication.refreshTokenExpiration).getTime())
    .map(refreshTokenExpirationMillies => new Date(refreshTokenExpirationMillies - this.tokenExpiryBuffer))
    .map(delay => new securityActions.RefreshTokenStartTimerAction(delay));

  @Effect()
  logout$: Observable<Action> = this.actions$
    .ofType(securityActions.LOGOUT)
    .mergeMap(() => this.store.select(fromRoot.getAuthenticationState).take(1))
    .mergeMap(state =>
      this.authenticationService.logout(state.tenant, state.username, state.authentication.accessToken)
        .map(() => new securityActions.LogoutSuccessAction())
        .catch((error) => of(new securityActions.LogoutSuccessAction()))
    );

  @Effect()
  refreshToken$: Observable<Action> = this.actions$
    .ofType(securityActions.REFRESH_ACCESS_TOKEN)
    .mergeMap(() => this.store.select(fromRoot.getAuthenticationState).take(1))
    .mergeMap(state =>
      this.authenticationService.refreshAccessToken(state.tenant)
        .map(authentication => new securityActions.RefreshAccessTokenSuccessAction(authentication))
        .catch((error) => of(new securityActions.RefreshAccessTokenFailAction(error)))
    );

  @Effect()
  startAccessTokenRefreshTimerAfterLogin$: Observable<Action> = this.actions$
    .ofType(securityActions.LOGIN_SUCCESS)
    .map((action: securityActions.LoginSuccessAction) => action.payload)
    .map(payload => new Date(payload.authentication.accessTokenExpiration).getTime())
    .map(accessTokenExpirationMillies => new Date(accessTokenExpirationMillies - this.tokenExpiryBuffer))
    .map(dueTime => new securityActions.RefreshAccessTokenStartTimerAction(dueTime));

  @Effect()
  startAccessTokenRefreshTimerAfterRefresh$: Observable<Action> = this.actions$
    .ofType(securityActions.REFRESH_ACCESS_TOKEN_SUCCESS)
    .map((action: securityActions.RefreshAccessTokenSuccessAction) => action.payload)
    .map(payload => new Date(payload.accessTokenExpiration).getTime())
    .map(accessTokenExpirationMillies => new Date(accessTokenExpirationMillies - this.tokenExpiryBuffer))
    .map(dueTime => new securityActions.RefreshAccessTokenStartTimerAction(dueTime));

  @Effect()
  refreshAccessTokenStartTimer$: Observable<Action> = this.actions$
    .ofType(securityActions.REFRESH_ACCESS_TOKEN_START_TIMER)
    .map((action: securityActions.RefreshAccessTokenStartTimerAction) => action.payload)
    .mergeMap(dueTime =>
      Observable.timer(dueTime)
        .switchMap(() => of(new securityActions.RefreshAccessTokenAction()))
    );

  @Effect()
  refreshTokenStartTimer$: Observable<Action> = this.actions$
    .ofType(securityActions.REFRESH_TOKEN_START_TIMER)
    .map((action: securityActions.RefreshTokenStartTimerAction) => action.payload)
    .mergeMap(dueTime =>
      Observable.timer(dueTime)
        .switchMap(() => of(new securityActions.LogoutAction()))
    );

  @Effect()
  changePassword$: Observable<Action> = this.actions$
    .ofType(securityActions.CHANGE_PASSWORD)
    .map((action: securityActions.ChangePasswordAction) => action.payload)
    .mergeMap(payload =>
      this.identityService.changePassword(payload.username, new Password(payload.password))
        .map(() => new securityActions.ChangePasswordSuccessAction())
        .catch(error => of(new securityActions.ChangePasswordFailAction(error)))
    );

  @Effect()
  logoutOnPasswordChange$: Observable<Action> = this.actions$
    .ofType(securityActions.CHANGE_PASSWORD_SUCCESS)
    .mergeMap(() => Observable.of(new securityActions.LogoutAction()));

  private fetchPermissions(tenantId: string, username: string, accessToken: string): Observable<FimsPermission[]> {
    return this.authenticationService.getUserPermissions(tenantId, username, accessToken)
      .flatMap((permissions: Permission[]) => Observable.from(permissions))
      .map((permission: Permission) => this.mapPermissions(permission))
      .reduce((acc: FimsPermission[], permissions: FimsPermission[]) => acc.concat(permissions), []);
  }

  private mapPermissions(permission: Permission): FimsPermission[] {
    const result: FimsPermission[] = [];
    const descriptor = this.idMapper.map(permission.permittableEndpointGroupIdentifier);

    if (descriptor) {
      const internalKey: PermissionId = descriptor.id;

      for (const operation of permission.allowedOperations){
        result.push({
          id: internalKey,
          accessLevel: operation
        });
      }
    }

    return result;
  }

  constructor(private actions$: Actions, private identityService: IdentityService, private authenticationService: AuthenticationService,
              private idMapper: PermittableGroupIdMapper, @Inject('tokenExpiryBuffer') private tokenExpiryBuffer: number,
              private store: Store<fromRoot.State>) {}
}
