import { IsBoolean, IsInt, IsOptional, IsPositive } from 'class-validator';
import { getConnection } from 'typeorm';
import { RunnerNotFoundError } from '../../../errors/RunnerErrors';
import { Runner } from '../../entities/Runner';
import { Scan } from '../../entities/Scan';

/**
 * This class is used to create a new Scan entity from a json body (post request).
 */
export abstract class CreateScan {
    /**
     * The scan's associated runner's id.
     * This is important to link ran distances to runners.
     */
    @IsInt()
    @IsPositive()
    runner: number;

    /**
     * Is the scan valid (for fraud reasons).
     * The determination of validity will work differently for every child class.
     * Default: true
     */
    @IsBoolean()
    @IsOptional()
    valid?: boolean = true;

    /**
     * The scan's distance in meters.
     * Can be set manually or derived from another object.
     */
    @IsInt()
    @IsPositive()
    public distance: number;

    /**
     * Creates a new Scan entity from this.
     */
    public async toEntity(): Promise<Scan> {
        let newScan = new Scan();

        newScan.distance = this.distance;
        newScan.valid = this.valid;
        newScan.runner = await this.getRunner();

        return newScan;
    }

    /**
     * Gets a runner based on the runner id provided via this.runner.
     */
    public async getRunner(): Promise<Runner> {
        const runner = await getConnection().getRepository(Runner).findOne({ id: this.runner });
        if (!runner) {
            throw new RunnerNotFoundError();
        }
        return runner;
    }
}