/*
 * 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 { Injectable } from '@angular/core';
import { map } from 'rxjs/operators';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { ApplicationSecurityService } from './applicationSecurity.service';
import { AppRoutingService } from './appRouting.service';

@Injectable()
export class AuthorizationGuard implements CanActivate {
  constructor(
    private appRoutingService: AppRoutingService,
    private applicationSecurityService: ApplicationSecurityService
  ) { }

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.applicationSecurityService.isLoggedIn().pipe(
      map(authState => {
        if (!authState)
          this.applicationSecurityService.locationCheck().subscribe(location => window.location.href = location);
        return !!authState;
      })
    );
  }
}
