import { IsBoolean, IsInt, IsOptional, IsPositive, IsString } from 'class-validator';
import crypto from 'crypto';
import { getConnection } from 'typeorm';
import * as uuid from 'uuid';
import { config } from '../../../config';
import { TrackNotFoundError } from '../../../errors/TrackErrors';
import { ScanStation } from '../../entities/ScanStation';
import { Track } from '../../entities/Track';

/**
 * This class is used to create a new StatsClient entity from a json body (post request).
 */
export class CreateScanStation {
    /**
     * The new station's description.
     */
    @IsString()
    @IsOptional()
    description?: string;

    /**
     * The station's associated track's id.
     */
    @IsInt()
    @IsPositive()
    track: number;

    /**
     * Is this station enabled?
     */
    @IsBoolean()
    @IsOptional()
    enabled?: boolean = true;

    /**
     * Converts this to a ScanStation entity.
     */
    public async toEntity(): Promise<ScanStation> {
        let newStation: ScanStation = new ScanStation();

        newStation.description = this.description;
        newStation.enabled = this.enabled;
        newStation.track = await this.getTrack();

        let newUUID = uuid.v4().toUpperCase();
        newStation.prefix = crypto.createHash("sha3-512").update(newUUID).digest('hex').substring(0, 7).toUpperCase();
        newStation.cleartextkey = newStation.prefix + "." + newUUID;
        newStation.key = crypto.createHmac("sha256", config.station_token_secret).update(newStation.cleartextkey).digest('hex');

        return newStation;
    }

    /**
     * Get's a track by it's id provided via this.track.
     * Used to link the new station to a track.
     */
    public async getTrack(): Promise<Track> {
        const track = await getConnection().getRepository(Track).findOne({ id: this.track });
        if (!track) {
            throw new TrackNotFoundError();
        }
        return track;
    }
}