import {Injectable, OnDestroy} from "@angular/core";
import {Subject} from "rxjs";
import {HttpClient} from "@angular/common/http";
import {WebsocketService} from "../websocket/websocket.service";
import {StatusUpdateService} from "./status-update.service";

export interface UserSession {
  userId: string,
  name: string,
  realm: string,
  domainId: string,
  roles: string[]
}

@Injectable({providedIn: 'root'})
export class AuthorizationService implements OnDestroy {

  private session: UserSession;

  public onSessionUpdate: Subject<UserSession> = new Subject<UserSession>();

  constructor(protected httpClient: HttpClient, protected websocketService: WebsocketService,
              protected statusUpdateService: StatusUpdateService) {}

  public getCurrentSession(): Promise<any> {
    if (this.session) return new Promise(resolve => resolve(this.session));
    return this.httpClient.get('session')
        .toPromise()
        .then((session: UserSession) => {
          this.session = session;
          this.onSessionUpdate.next(session);

          if (this.hasRole('security_administrator')) {
            this.websocketService.subscribe(({data}) => {
              let parsedObj = JSON.parse(data);

              if (parsedObj && parsedObj.traceId) {
                if (parsedObj.className === 'update' || parsedObj.className === 'processError') {
                  this.statusUpdateService.update(parsedObj);
                }
              }
            });
          }
          return session;
        })
  }

  isAuthorized(): boolean {
    return !!this.session;
  }

  hasAnyRole(roles: string[]): boolean {
    return this.isAuthorized() && roles.some(role => this.getRoles().includes(role));
  }

  hasRole(role: string): boolean {
    return this.isAuthorized() && this.getRoles().includes(role);
  }

  getUserId(): string{
    return this.isAuthorized() ? this.session.userId: null;
  }

  getName(): string {
    return this.isAuthorized() ? this.session.name : null;
  }

  getRealm(): string {
    return this.isAuthorized() ? this.session.realm : null;
  }

  getDomainId(): string {
    return this.isAuthorized() ? this.session.domainId : null;
  }

  getRoles(): string[] {
    return this.isAuthorized() ? this.session.roles : null;
  }

  ngOnDestroy(): void {
    this.websocketService.unsubscribe();
  }
}
