/*
 * Copyright (C) 2019 StApps
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */
import {SCLicensePlate, SCThingOriginType, SCThingRemoteOrigin, SCThings} from '@openstapps/core';
import {createUUID} from './common.js';

/**
 * Provides abstracted methods for the connector execution process
 *
 * By extending this class connector-developers only need to implement the load and transform of the data
 * Pushing the data to the backend will be handled automatically
 * @template T Any serializable type
 */
export abstract class Connector<T extends SCThings> {
  /**
   * License plate of the school
   */
  protected licensePlate: SCLicensePlate;

  /**
   * Name of the connector
   */
  public origin: string;

  /**
   * Abstract constructor for a connector
   * @param licensePlate License plate of the school
   * @param origin Name of the connector
   */
  constructor(licensePlate: SCLicensePlate, origin: string) {
    this.licensePlate = licensePlate;
    this.origin = origin;
  }

  /**
   * Will fetch items from systems
   *
   * Implementation according to your schools requirements
   */
  protected abstract fetchItems(): Promise<T[]>;

  /**
   * Creates a remote origin with the current date-time
   */
  createRemoteOrigin(): SCThingRemoteOrigin {
    return {
      indexed: new Date().toISOString(),
      name: this.origin,
      type: SCThingOriginType.Remote,
    };
  }

  /**
   * Fetches items and generates missing uids
   */
  async getItems(): Promise<T[]> {
    const importedItems = await this.fetchItems();

    for (const item of importedItems) {
      if (item.uid.length === 0) {
        item.uid = createUUID(item, this.licensePlate);
      }
    }

    return importedItems;
  }
}
