package ru.yandex.canvas.service.video;

import ru.yandex.canvas.model.stillage.StillageFileInfo;
import ru.yandex.canvas.service.FileValidator;
import ru.yandex.canvas.service.TankerKeySet;
import ru.yandex.canvas.service.VideoLimitsInterface;

public class AudioValidator extends FileValidator {
    private static final Integer FILESIZE_MAX = 10_000_000;
    private static final Long SAMPLE_RATE_MIN = 44100L;

    private AudioUploadService.MetaDataInfo metaDataInfo;
    private StillageFileInfo stillageFileInfo;
    private VideoLimitsInterface limits;

    public AudioValidator(StillageFileInfo stillageFileInfo,
                          AudioUploadService.MetaDataInfo metaDataInfo,
                          VideoLimitsInterface limits) {
        super(TankerKeySet.VIDEO_VALIDATION_MESSAGES);
        this.stillageFileInfo = stillageFileInfo;
        this.metaDataInfo = metaDataInfo;
        this.limits = limits;
    }

    @Override
    public void validate() {
        if (!stillageFileInfo.getContentGroup().equalsIgnoreCase("AUDIO")
                && !(stillageFileInfo.getContentGroup().equalsIgnoreCase("VIDEO")
                && stillageFileInfo.getMimeType().equalsIgnoreCase("video/mp4"))
        ) {
            addErrorMessage("invalid_audio_file_format");
            throwValidationErrors();
        }
        if (stillageFileInfo.getFileSize() > FILESIZE_MAX) {
            addErrorMessage("invalid_audio_filesize", stillageFileInfo.getFileSize(), FILESIZE_MAX);
        }
        if (metaDataInfo.getDuration() == null || metaDataInfo.getDuration() < limits.getAudioDurationMin() ||
                metaDataInfo.getDuration() > limits.getAudioDurationMax() + 0.5) {
            addErrorMessage("invalid_audio_duration", metaDataInfo.getDuration(),
                    limits.getAudioDurationMin(), limits.getAudioDurationMax());
        }
        if (stillageFileInfo.getContentGroup().equalsIgnoreCase("AUDIO")) {
            checkAudioQuality(metaDataInfo.getStream().getBaseInfo());
        }
        if (stillageFileInfo.getContentGroup().equalsIgnoreCase("VIDEO")) {
            if (!metaDataInfo.getVideoStreams().isEmpty()) {
                addErrorMessage("invalid_audio_file_format");
            }
            if (metaDataInfo.getAudioStreams().size() != 1) {
                addErrorMessage("audio_required");
            }
            if (!metaDataInfo.getAudioStreams().isEmpty()) {
                checkAudioQuality(metaDataInfo.getAudioStreams().get(0).getBaseInfo());
            }
        }
        throwValidationErrors();
    }

    private void checkAudioQuality(AudioUploadService.MetaDataInfo.MetaDataInfoStreamBaseInfo baseInfo) {
        if (!limits.getAllowedAudioCodecs().contains(baseInfo.getCodec())) {
            addErrorMessage("invalid_audio_codec", joinArgs(limits.getAllowedAudioCodecs()));
        }
        if (baseInfo.getSampleRate() < SAMPLE_RATE_MIN) {
            addErrorMessage("invalid_audio_samplerate");
        }
    }

    private String joinArgs(Iterable<String> args) {
        return String.join(", ", args);
    }
}
