import {
  ActivatedRouteSnapshot,
  CanActivate,
  Router,
  RouterStateSnapshot,
  UrlTree
} from "@angular/router";
import {Observable} from "rxjs";
import {Injectable} from "@angular/core";
import {AuthorizationService} from "../service/authorization.service";
import {TokenProvider} from "../provider/token.provider";

@Injectable({providedIn: 'root'})
export class RolesGuard implements CanActivate {

  protected readonly allowedRoles: string[] = [];

  constructor(protected authService: AuthorizationService,
              protected tokenProvider: TokenProvider,
              protected router: Router) {
  }

  async canActivate(
      route: ActivatedRouteSnapshot, state: RouterStateSnapshot
  ): Promise<boolean | UrlTree> {
    if (!await this.tokenProvider.getToken()) {
      return this.getUrlOnFailure()
    }

    if (!this.authService.isAuthorized()) {
      return this.authService.getCurrentSession()
          .then(() => this.checkRoles() ? true : this.getUrlOnFailure())
          .catch(() => this.getUrlOnFailure());
    }
    else {
      return this.checkRoles();
    }
  }

  protected getUrlOnFailure(): UrlTree {
    return null;
  }

  protected checkRoles(): boolean {
    return this.allowedRoles.length === 0
           || this.authService.hasAnyRole(this.allowedRoles);
  }
}