/*!
 * Copyright (c) 2021 Eclipse Foundation, Inc.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * Contributors:
 *   Eric Poirier <eric.poirier@eclipse-foundation.org>
 *
 * SPDX-License-Identifier: EPL-2.0
 */

import parse from 'parse-link-header';
import { validateURL } from '../utils/utils';
import 'isomorphic-fetch';

const eclipseProjectsUrl = "https://projects.eclipse.org/projects/";

const throwFetchError = ({ status, statusText } = response) => { 
    throw `${status}: ${statusText}` 
};

const getProjectsDataFromAPI = (url, projects = []) => {
  if (validateURL(url)) {
    return new Promise((resolve, reject) =>
      fetch(url)
        .then((response) => {
          if (response.status !== 200) throwFetchError(response);

          response
            .json()
            .then((data) => {
              projects = projects.concat(data);
              const linkHeader = parse(response.headers.get('Link'));
              if (linkHeader?.next && typeof linkHeader.next?.url === 'string') {
                getProjectsDataFromAPI(linkHeader.next.url, projects).then(resolve).catch(reject);
              } else {
                projects.forEach((project, key) => {
                  projects[key].version = 'none';
                  if (project.releases[0]) {
                    projects[key].version = project.releases[0].name;
                  }
                  if (typeof projects[key].website_url === "undefined" || projects[key].website_url === "") {
                    projects[key].website_url = eclipseProjectsUrl + projects[key].project_id;
                  }
                });

                projects.sort((a, b) => a.name.localeCompare(b.name));
                resolve(projects);
              }
            })
            .catch(reject);
        })
        .catch((err) => {
          reject(err);
        })
    );
  }
};


const getProjectsDataFromStaticSource = (url) => {
    if (!validateURL(url)) return;

    return new Promise((resolve, reject) => 
        fetch(url)
            .then(response => {
                if (response.status !== 200) throw `${response.status}: ${response.statusText}`
                
                response
                    .json()
                    .then((projects) => {
                      projects.forEach((_, key) => {
                          if (typeof projects[key].website_url === "undefined" || projects[key].website_url === "") {
                              projects[key].website_url = eclipseProjectsUrl + projects[key].project_id;
                          }
                      });

                      projects.sort((a, b) => a.name.localeCompare(b.name));
                      resolve(projects);
                    })
                    .catch(reject)
                })
            .catch((err) => reject(err))
    )
}

export const getProjectsData = (url, isStaticSource) => {
    let projects;

    if (isStaticSource) {
        projects = getProjectsDataFromStaticSource(url);
    } else {
        projects = getProjectsDataFromAPI(url);
    }

    return projects;
}

export default getProjectsData;
