/*
 * Copyright (C) 2022 Savoir-faire Linux Inc.
 *
 * 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 { Router } from 'express';
import asyncHandler from 'express-async-handler';
import { HttpStatusCode } from 'jami-web-common';
import { getLinkPreview } from 'link-preview-js';
import * as linkify from 'linkifyjs';

import { authenticateToken } from '../middleware/auth.js';

export const linkPreviewRouter = Router();

// Result of getLinkPreview from link-preview-js
type LinkPreviewJs = {
  url: string;
  title: string;
  siteName: string | undefined;
  description: string | undefined;
  mediaType: string;
  contentType: string | undefined;
  images: string[];
  videos: {
    url: string | undefined;
    secureUrl: string | null | undefined;
    type: string | null | undefined;
    width: string | undefined;
    height: string | undefined;
  }[];
  favicons: string[];
};

linkPreviewRouter.use(authenticateToken);

const linkPreviewOptions = {
  // Allowing redirection from http to https
  // Code from doc: https://github.com/ospfranco/link-preview-js#redirections
  followRedirects: 'manual',
  handleRedirects: (baseURL: string, forwardedURL: string) => {
    const urlObj = new URL(baseURL);
    const forwardedURLObj = new URL(forwardedURL);
    if (
      forwardedURLObj.hostname === urlObj.hostname ||
      forwardedURLObj.hostname === 'www.' + urlObj.hostname ||
      'www.' + forwardedURLObj.hostname === urlObj.hostname
    ) {
      return true;
    } else {
      return false;
    }
  },
} as const;

linkPreviewRouter.get(
  '/',
  asyncHandler(async (req, res) => {
    const url = req.query.url;

    if (typeof url !== 'string') {
      res.status(HttpStatusCode.BadRequest).send('Invalid query parameters');
      return;
    }

    // Add 'http' or 'https' if absent. This is required by getLinkPreview
    const sanitizedUrl = linkify.find(url)[0]?.href;

    if (!sanitizedUrl) {
      res.status(HttpStatusCode.BadRequest).send('Invalid url');
      return;
    }

    try {
      const detailedLinkPreview = (await getLinkPreview(sanitizedUrl, linkPreviewOptions)) as LinkPreviewJs;
      const linkPreview = {
        title: detailedLinkPreview.title,
        description: detailedLinkPreview.description,
        // We might eventualy want to compare the images in order to select the best fit
        // https://andrejgajdos.com/how-to-create-a-link-preview/
        image: detailedLinkPreview.images[0] ?? detailedLinkPreview.favicons[0],
      };
      res.json(linkPreview).end();
    } catch (e) {
      res.status(HttpStatusCode.NotFound).send('Could not access url');
    }
  })
);
