import { StorageUtil, ExpiredUnit } from '../utils/storage.util';
import { fromEvent, Observable } from 'rxjs';
import { filter } from 'rxjs/operators';

export class StorageService {
  constructor(private storage: Storage) {}

  get<T>(key: string): T | null {
    return StorageUtil.get(this.storage, key);
  }

  set<T>(
    key: string,
    value: T,
    expiredAt: number = 0,
    expiredUnit: ExpiredUnit = 'd'
  ) {
    return StorageUtil.set(this.storage, key, value, expiredAt, expiredUnit);
  }

  remove(key: string | RegExp) {
    if (typeof key === 'string') {
      StorageUtil.remove(this.storage, key);
      return;
    }
    let index = 0;
    let next = StorageUtil.key(this.storage, index);
    const ls: string[] = [];
    while (next) {
      if (key.test(next)) {
        ls.push(next);
      }
      next = StorageUtil.key(this.storage, ++index);
    }
    ls.forEach(v => StorageUtil.remove(this.storage, v));
  }

  clear() {
    this.storage.clear();
  }

  observe(key: string): Observable<StorageEvent> {
    return fromEvent<StorageEvent>(window, 'storage').pipe(
      filter(event => event.storageArea === this.storage),
      filter(event => event.key === key)
    );
  }
}
