/*
 * Copyright (C) 2022 Robert Bosch GmbH Copyright (C) 2022 Robert Bosch Manufacturing Solutions GmbH, Germany. All rights reserved.
 */

import { Injectable } from '@angular/core';
import { AbstractSecurityStorage } from 'angular-auth-oidc-client';
import { IMacmaAuthModuleConfig } from '../macma-auth.options';

export const STORAGE_SCOPE_REDIRECT_QUERY_PARAMETER = 'redirectStorageScope';

@Injectable()
export class MacmaStorageService implements AbstractSecurityStorage {
  private _storageScope: string;
  private storageScopeInitialized = false;

  get storageScope(): string {
    this.ensureScopeInitialized();
    return this._storageScope;
  }

  read(key: string) {
    return sessionStorage.getItem(this.makeKey(key));
  }

  write(key: string, value: any): void {
    sessionStorage.setItem(this.makeKey(key), value);
  }

  remove(key: string): void {
    sessionStorage.removeItem(this.makeKey(key));
  }

  clear(): void {
    if (this._storageScope != null) {
      for (let i = 0; i < sessionStorage.length; ++i) {
        const key = sessionStorage.key(i);
        if (key && key.startsWith(this._storageScope)) {
          sessionStorage.removeItem(key);
        }
      }
    } else {
      sessionStorage.clear();
    }
  }

  initializeStorageScope(config: IMacmaAuthModuleConfig): void {
    if (config.queryParamStorageScopeDiscriminator === STORAGE_SCOPE_REDIRECT_QUERY_PARAMETER) {
      throw new Error(`Storage scope discriminator cannot be reserved name "${STORAGE_SCOPE_REDIRECT_QUERY_PARAMETER}"`)
    }
    if (config.queryParamStorageScopeDiscriminator) {
      const urlParams = new URLSearchParams(window.location.search);
      this._storageScope = urlParams.get(STORAGE_SCOPE_REDIRECT_QUERY_PARAMETER) ?? urlParams.get(config.queryParamStorageScopeDiscriminator);
      if (config.debugAuthentication) {
        if (this._storageScope) {
          console.log(`using storage scope ${this._storageScope}`);
        } else {
          console.log(`Using unscoped storage since URL parameter ${config.queryParamStorageScopeDiscriminator} was not found`);
        }
      }
    }
    this.storageScopeInitialized = true;
  }

  private makeKey(key: string): string {
    this.ensureScopeInitialized();
    if (this._storageScope != null) {
      return `${this._storageScope}-${key}`;
    }
    return key;
  }

  private ensureScopeInitialized(): void {
    if (!this.storageScopeInitialized) {
      console.error('Storage scope not initialized. This should not happen');
    }
  }
}
