/*
 * Copyright (C) 2019, 2020 StApps
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
import {
  SCBook,
  SCBulkAddRoute,
  SCBulkDoneRoute,
  SCBulkRequest,
  SCBulkRoute,
  SCNotFoundErrorResponse,
} from '@openstapps/core';
import {expect} from 'chai';
import {bulk, DEFAULT_TEST_TIMEOUT} from '../common.js';
import {testApp} from '../tests-setup.js';
import {v4} from 'uuid';
import bookFile from '@openstapps/core/test/resources/indexable/Book.2.json' assert {type: 'json'};

const book = bookFile.instance as SCBook;

describe('Bulk routes', async function () {
  // increase timeout for the suite
  this.timeout(DEFAULT_TEST_TIMEOUT);

  let request: SCBulkRequest;
  let bulkRoute: SCBulkRoute;
  let bulkAddRoute: SCBulkAddRoute;
  let bulkDoneRoute: SCBulkDoneRoute;

  before(function () {
    request = {
      expiration: bulk.expiration,
      source: bulk.source,
      type: bulk.type,
    };
    bulkRoute = new SCBulkRoute();
    bulkAddRoute = new SCBulkAddRoute();
    bulkDoneRoute = new SCBulkDoneRoute();
  });

  it('should create bulk', async function () {
    const {status, body, error} = await testApp
      .post(bulkRoute.urlPath)
      .set('Content-Type', 'application/json')
      .send(request);

    expect(status).to.be.equal(bulkRoute.statusCodeSuccess);
    expect(error).to.be.equal(false);
    expect(body.uid).to.be.a('string');
    expect(body).to.deep.equal({...bulk, uid: body.uid});
  });

  it('should return (throw) error if a bulk with the provided UID cannot be found when adding to a bulk', async function () {
    await testApp.post(bulkRoute.urlPath).set('Content-Type', 'application/json').send(request);
    const bulkAddRouteUrlPath = bulkAddRoute.urlPath.toLocaleLowerCase().replace(':uid', v4());

    const {status} = await testApp
      .post(bulkAddRouteUrlPath)
      .set('Content-Type', 'application/json')
      .send(book);

    expect(status).to.be.equal(new SCNotFoundErrorResponse().statusCode);
  });

  it('should add to a created bulk', async function () {
    const response = await testApp
      .post(bulkRoute.urlPath)
      .set('Content-Type', 'application/json')
      .send(request);
    const bulkAddRouteUrlPath = bulkAddRoute.urlPath.toLocaleLowerCase().replace(':uid', response.body.uid);

    const {status, body} = await testApp
      .post(bulkAddRouteUrlPath)
      .set('Content-Type', 'application/json')
      .send(book);

    expect(status).to.be.equal(bulkAddRoute.statusCodeSuccess);
    expect(body).to.be.deep.equal({});
  });

  it('should return (throw) error if a bulk with the provided UID cannot be found when closing a bulk (done)', async function () {
    await testApp.post(bulkRoute.urlPath).set('Content-Type', 'application/json').send(request);
    const bulkDoneRouteUrlPath = bulkDoneRoute.urlPath.toLocaleLowerCase().replace(':uid', 'a-wrong-uid');

    const {status} = await testApp
      .post(bulkDoneRouteUrlPath)
      .set('Content-Type', 'application/json')
      .send({});

    expect(status).to.be.equal(new SCNotFoundErrorResponse().statusCode);
  });

  it('should close the bulk (done)', async function () {
    const response = await testApp
      .post(bulkRoute.urlPath)
      .set('Content-Type', 'application/json')
      .send(request);
    const bulkDoneRouteurlPath = bulkDoneRoute.urlPath.toLocaleLowerCase().replace(':uid', response.body.uid);

    const response2 = await testApp
      .post(bulkDoneRouteurlPath)
      .set('Content-Type', 'application/json')
      .send({});

    expect(response2.status).to.be.equal(bulkDoneRoute.statusCodeSuccess);
  });
});
