import { join } from 'path';
import { LOCAL_AAI_CFG_DIR, REMOTE_AAI_CFG_DIR_LINUX } from '../paths';
import {
  getLocalDeviceConfigDirectoryPath,
  getRemoteDeviceConfigDirectoryPath
} from './device-paths';

export const DEVICE_CERTIFICATES_DIRECTORY_NAME = 'certificates';

/*===================================================================
                      Device Certificates
===================================================================*/

export const DEVICE_PRIVATE_KEY_FILE_NAME = 'aai-device-private-key.pem.key';
export const DEVICE_CERTIFICATE_FILE_NAME = 'aai-device-cert.pem.crt';
export const DEVICE_CERTIFICATE_ID_FILE_NAME = 'aai-device-cert-id.txt';
export const DEVICE_PUBLIC_KEY_FILE_NAME = 'alwaysai.public.pem.key';
export const DEVICE_ROOT_CERT_FILE_NAME = 'AmazonRootCA1.pem';

/*===================================================================
                      Certificate Path Factory
===================================================================*/

export abstract class DeviceCertificates {
  baseDir: string;
  certificateDirectoryName: string = DEVICE_CERTIFICATES_DIRECTORY_NAME;
  certificateFileName: string = DEVICE_CERTIFICATE_FILE_NAME;
  privateKeyFileName: string = DEVICE_PRIVATE_KEY_FILE_NAME;
  publicKeyFileName: string = DEVICE_PUBLIC_KEY_FILE_NAME;
  certificateIdFileName: string = DEVICE_CERTIFICATE_ID_FILE_NAME;
  rootCertificateFileName: string = DEVICE_ROOT_CERT_FILE_NAME;

  constructor(baseDir: string) {
    this.baseDir = baseDir;
  }

  /**
   * Returns the upper level (home) directory where all
   * certificates are stored
   */
  public getBaseCertificateDirectoryPath(): string {
    return this.baseDir;
  }

  /**
   * Returns the name of the folder where the certificates are
   * stored inside the base certificate directory
   */
  public getCertificateDirectoryName(): string {
    return this.certificateDirectoryName;
  }

  /**
   * Returns the full path to the folder where the certificates
   * are directly stored. This is the file you would write to
   * on device init, or remove on device clean.
   */
  public getCertificateDirectoryPath(): string {
    return join(this.baseDir, this.certificateDirectoryName);
  }

  public getPrivateKeyFileName(): string {
    return this.privateKeyFileName;
  }

  public getPrivateKeyFilePath(): string {
    return join(this.getCertificateDirectoryPath(), this.privateKeyFileName);
  }

  public getCertificateFileName(): string {
    return this.certificateFileName;
  }

  public getCertificateFilePath(): string {
    return join(this.getCertificateDirectoryPath(), this.certificateFileName);
  }

  public getCertificateIdFileName(): string {
    return this.certificateIdFileName;
  }

  public getCertificateIdFilePath(): string {
    return join(this.getCertificateDirectoryPath(), this.certificateIdFileName);
  }

  public getPublicKeyFileName(): string {
    return this.publicKeyFileName;
  }

  public getPublicKeyFilePath(): string {
    return join(this.getCertificateDirectoryPath(), this.publicKeyFileName);
  }

  public getRootCertificateFileName(): string {
    return this.rootCertificateFileName;
  }

  public getRootCertificateFilePath(): string {
    return join(
      this.getCertificateDirectoryPath(),
      this.rootCertificateFileName
    );
  }
}

export class RemoteLegacyDeviceCertificates extends DeviceCertificates {
  constructor(baseDir: string = REMOTE_AAI_CFG_DIR_LINUX) {
    super(baseDir);
  }
}

export class RemoteDeviceCertificates extends DeviceCertificates {
  constructor(baseDir: string = getRemoteDeviceConfigDirectoryPath()) {
    super(baseDir);
  }
}

export class LocalLegacyDeviceCertificates extends DeviceCertificates {
  constructor(baseDir: string = LOCAL_AAI_CFG_DIR) {
    super(baseDir);
  }
}

export class LocalDeviceCertificates extends DeviceCertificates {
  constructor(baseDir: string = getLocalDeviceConfigDirectoryPath()) {
    super(baseDir);
  }
}

/*===================================================================
              local certificate file setup
===================================================================*/

const localDeviceCertificates = new LocalDeviceCertificates();
export const LOCAL_DEVICE_CREDENTIALS_DIR =
  localDeviceCertificates.getBaseCertificateDirectoryPath();
export const LOCAL_CERT_AND_KEY_DIR =
  localDeviceCertificates.getCertificateDirectoryPath();
export const DEVICE_PRIVATE_KEY_FILE_PATH =
  localDeviceCertificates.getPrivateKeyFilePath();
export const DEVICE_CERTIFICATE_FILE_PATH =
  localDeviceCertificates.getCertificateFilePath();

/*===================================================================
              remote certificate file setup
===================================================================*/
const remoteDeviceCertificates = new RemoteDeviceCertificates();
export const REMOTE_DEVICE_CREDENTIALS_DIR =
  remoteDeviceCertificates.getBaseCertificateDirectoryPath();
export const REMOTE_CERT_AND_KEY_DIR_LINUX =
  remoteDeviceCertificates.getCertificateDirectoryPath();
