<template>
  <b-card no-body>
    <b-tabs card no-fade pills>
      <b-tab active title="File Scan">
        <b-input-group>
          <b-form-file v-model="file" placeholder="Select or drop files here"/>
          <b-input-group-append>
            <b-button :disabled="!file || uploading" variant="primary" @click="scanFile">Scan</b-button>
          </b-input-group-append>
        </b-input-group>

        <b-input id="callback-url" v-model="callbackUrl" class="mt-3"
                 placeholder="Optional callback URL. I.e. https://pipedream.com/" type="url"/>

        <b-progress v-if="uploading" :value="progress" animated class="mt-3"/>
      </b-tab>

      <b-tab title="URL Scan">
        <b-input-group>
          <b-input v-model="url" placeholder="https://secure.eicar.org/eicar.com.txt" type="url"/>
          <b-input-group-append>
            <b-button :disabled="!isUrl(url)" variant="primary" @click="scanUrl">Scan</b-button>
          </b-input-group-append>
        </b-input-group>

        <b-input id="callback-url" v-model="callbackUrl" class="mt-3"
                 placeholder="Optional callback URL. I.e. https://pipedream.com/" type="url"/>
      </b-tab>
    </b-tabs>
  </b-card>
</template>

<script lang="ts">
import Vue from 'vue';

import ScanResult from '~/models/scan-result';

export default Vue.extend({
  data() {
    return {
      uploading: false,
      progress: 0,

      file: null as File | null,
      url: '' as string,
      callbackUrl: '' as string
    }
  },

  methods: {
    isUrl(url: string): boolean {
      return /(http|https):\/\/(\w+:?\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@\-\/]))?/.test(url);
    },

    async scanFile() {
      if (!this.file || this.uploading)
        return

      const data = new FormData();

      data.append('file', this.file, this.file.name);

      if (this.isUrl(this.callbackUrl))
        data.append('callbackUrl', this.callbackUrl);

      try {
        this.uploading = true;

        const result = await this.$axios.$post<ScanResult>('queue/file', data, {
          onUploadProgress: (progressEvent) => {
            if (progressEvent.total == 0)
              return;

            this.progress = progressEvent.loaded / progressEvent.total * 100;
          }
        });

        await this.$router.push({name: 'id', params: {id: result.id}});
      } finally {
        this.progress = 0;
        this.uploading = false;
      }
    },

    async scanUrl() {
      if (!this.isUrl(this.url))
        return;

      const data = new FormData();

      data.append('url', this.url);

      if (this.isUrl(this.callbackUrl))
        data.append('callbackUrl', this.callbackUrl);

      const result = await this.$axios.$post<ScanResult>('queue/url', data);

      await this.$router.push({name: 'id', params: {id: result.id}});
    }
  }
});
</script>
