/*
 * Copyright (C) 2016 Canonical Ltd.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2 or version 3 of the License.
 * See http://www.gnu.org/copyleft/lgpl.html the full text of the license.
 */

#include <snapd-glib/snapd-glib.h>

#include "Snapd/snap.h"

QSnapdSnap::QSnapdSnap(void *snapd_object, QObject *parent)
    : QSnapdWrappedObject(g_object_ref(snapd_object), g_object_unref, parent) {}

int QSnapdSnap::appCount() const {
  GPtrArray *apps;

  apps = snapd_snap_get_apps(SNAPD_SNAP(wrapped_object));
  return apps != NULL ? apps->len : 0;
}

QSnapdApp *QSnapdSnap::app(int n) const {
  GPtrArray *apps;

  apps = snapd_snap_get_apps(SNAPD_SNAP(wrapped_object));
  if (apps == NULL || n < 0 || (guint)n >= apps->len)
    return NULL;
  return new QSnapdApp(apps->pdata[n]);
}

QString QSnapdSnap::base() const {
  return snapd_snap_get_base(SNAPD_SNAP(wrapped_object));
}

QString QSnapdSnap::broken() const {
  return snapd_snap_get_broken(SNAPD_SNAP(wrapped_object));
}

int QSnapdSnap::categoryCount() const {
  GPtrArray *categories;

  categories = snapd_snap_get_categories(SNAPD_SNAP(wrapped_object));
  return categories != NULL ? categories->len : 0;
}

QSnapdCategory *QSnapdSnap::category(int n) const {
  GPtrArray *categories;

  categories = snapd_snap_get_categories(SNAPD_SNAP(wrapped_object));
  if (categories == NULL || n < 0 || (guint)n >= categories->len)
    return NULL;
  return new QSnapdCategory(categories->pdata[n]);
}

QString QSnapdSnap::channel() const {
  return snapd_snap_get_channel(SNAPD_SNAP(wrapped_object));
}

int QSnapdSnap::channelCount() const {
  GPtrArray *channels;

  channels = snapd_snap_get_channels(SNAPD_SNAP(wrapped_object));
  return channels != NULL ? channels->len : 0;
}

QSnapdChannel *QSnapdSnap::channel(int n) const {
  GPtrArray *channels;

  channels = snapd_snap_get_channels(SNAPD_SNAP(wrapped_object));
  if (channels == NULL || n < 0 || (guint)n >= channels->len)
    return NULL;
  return new QSnapdChannel(channels->pdata[n]);
}

QSnapdChannel *QSnapdSnap::matchChannel(const QString &name) const {
  SnapdChannel *channel = snapd_snap_match_channel(SNAPD_SNAP(wrapped_object),
                                                   name.toStdString().c_str());
  if (channel == NULL)
    return NULL;
  return new QSnapdChannel(channel);
}

QStringList QSnapdSnap::commonIds() const {
  GStrv common_ids = snapd_snap_get_common_ids(SNAPD_SNAP(wrapped_object));
  QStringList result;
  for (int i = 0; common_ids[i] != NULL; i++)
    result.append(common_ids[i]);
  return result;
}

QSnapdEnums::SnapConfinement QSnapdSnap::confinement() const {
  switch (snapd_snap_get_confinement(SNAPD_SNAP(wrapped_object))) {
  case SNAPD_CONFINEMENT_STRICT:
    return QSnapdEnums::SnapConfinementStrict;
  case SNAPD_CONFINEMENT_CLASSIC:
    return QSnapdEnums::SnapConfinementClassic;
  case SNAPD_CONFINEMENT_DEVMODE:
    return QSnapdEnums::SnapConfinementDevmode;
  case SNAPD_CONFINEMENT_UNKNOWN:
  default:
    return QSnapdEnums::SnapConfinementUnknown;
  }
}

QString QSnapdSnap::contact() const {
  return snapd_snap_get_contact(SNAPD_SNAP(wrapped_object));
}

QString QSnapdSnap::description() const {
  return snapd_snap_get_description(SNAPD_SNAP(wrapped_object));
}

QString QSnapdSnap::developer() const {
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  return snapd_snap_get_developer(SNAPD_SNAP(wrapped_object));
  G_GNUC_END_IGNORE_DEPRECATIONS
}

bool QSnapdSnap::devmode() const {
  return snapd_snap_get_devmode(SNAPD_SNAP(wrapped_object));
}

qint64 QSnapdSnap::downloadSize() const {
  return snapd_snap_get_download_size(SNAPD_SNAP(wrapped_object));
}

static QDateTime convertDateTime(GDateTime *datetime) {
  if (datetime == NULL)
    return QDateTime();

  QDate date(g_date_time_get_year(datetime), g_date_time_get_month(datetime),
             g_date_time_get_day_of_month(datetime));
  QTime time(g_date_time_get_hour(datetime), g_date_time_get_minute(datetime),
             g_date_time_get_second(datetime),
             g_date_time_get_microsecond(datetime) / 1000);
  return QDateTime(date, time, Qt::OffsetFromUTC,
                   g_date_time_get_utc_offset(datetime) / 1000000);
}

QDateTime QSnapdSnap::hold() const {
  return convertDateTime(snapd_snap_get_hold(SNAPD_SNAP(wrapped_object)));
}

QDateTime QSnapdSnap::proceedTime() const {
  return convertDateTime(
      snapd_snap_get_proceed_time(SNAPD_SNAP(wrapped_object)));
}

QString QSnapdSnap::icon() const {
  return snapd_snap_get_icon(SNAPD_SNAP(wrapped_object));
}

QString QSnapdSnap::id() const {
  return snapd_snap_get_id(SNAPD_SNAP(wrapped_object));
}

QDateTime QSnapdSnap::installDate() const {
  return convertDateTime(
      snapd_snap_get_install_date(SNAPD_SNAP(wrapped_object)));
}

qint64 QSnapdSnap::installedSize() const {
  return snapd_snap_get_installed_size(SNAPD_SNAP(wrapped_object));
}

bool QSnapdSnap::jailmode() const {
  return snapd_snap_get_jailmode(SNAPD_SNAP(wrapped_object));
}

QString QSnapdSnap::license() const {
  return snapd_snap_get_license(SNAPD_SNAP(wrapped_object));
}

int QSnapdSnap::mediaCount() const {
  GPtrArray *media;

  media = snapd_snap_get_media(SNAPD_SNAP(wrapped_object));
  return media != NULL ? media->len : 0;
}

QSnapdMedia *QSnapdSnap::media(int n) const {
  GPtrArray *media;

  media = snapd_snap_get_media(SNAPD_SNAP(wrapped_object));
  if (media == NULL || n < 0 || (guint)n >= media->len)
    return NULL;
  return new QSnapdMedia(media->pdata[n]);
}

QString QSnapdSnap::mountedFrom() const {
  return snapd_snap_get_mounted_from(SNAPD_SNAP(wrapped_object));
}

QString QSnapdSnap::name() const {
  return snapd_snap_get_name(SNAPD_SNAP(wrapped_object));
}

int QSnapdSnap::priceCount() const {
  GPtrArray *prices;

  prices = snapd_snap_get_prices(SNAPD_SNAP(wrapped_object));
  return prices != NULL ? prices->len : 0;
}

QSnapdPrice *QSnapdSnap::price(int n) const {
  GPtrArray *prices;

  prices = snapd_snap_get_prices(SNAPD_SNAP(wrapped_object));
  if (prices == NULL || n < 0 || (guint)n >= prices->len)
    return NULL;
  return new QSnapdPrice(prices->pdata[n]);
}

bool QSnapdSnap::isPrivate() const {
  return snapd_snap_get_private(SNAPD_SNAP(wrapped_object));
}

QString QSnapdSnap::publisherDisplayName() const {
  return snapd_snap_get_publisher_display_name(SNAPD_SNAP(wrapped_object));
}

QString QSnapdSnap::publisherId() const {
  return snapd_snap_get_publisher_id(SNAPD_SNAP(wrapped_object));
}

QString QSnapdSnap::publisherUsername() const {
  return snapd_snap_get_publisher_username(SNAPD_SNAP(wrapped_object));
}

QSnapdEnums::PublisherValidation QSnapdSnap::publisherValidation() const {
  switch (snapd_snap_get_publisher_validation(SNAPD_SNAP(wrapped_object))) {
  case SNAPD_PUBLISHER_VALIDATION_UNPROVEN:
    return QSnapdEnums::PublisherValidationUnproven;
  case SNAPD_PUBLISHER_VALIDATION_STARRED:
    return QSnapdEnums::PublisherValidationStarred;
  case SNAPD_PUBLISHER_VALIDATION_VERIFIED:
    return QSnapdEnums::PublisherValidationVerified;
  case SNAPD_PUBLISHER_VALIDATION_UNKNOWN:
  default:
    return QSnapdEnums::PublisherValidationUnknown;
  }
}

QString QSnapdSnap::revision() const {
  return snapd_snap_get_revision(SNAPD_SNAP(wrapped_object));
}

int QSnapdSnap::screenshotCount() const {
  GPtrArray *screenshots;

  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  screenshots = snapd_snap_get_screenshots(SNAPD_SNAP(wrapped_object));
  G_GNUC_END_IGNORE_DEPRECATIONS
  return screenshots != NULL ? screenshots->len : 0;
}

QSnapdScreenshot *QSnapdSnap::screenshot(int n) const {
  GPtrArray *screenshots;

  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  screenshots = snapd_snap_get_screenshots(SNAPD_SNAP(wrapped_object));
  G_GNUC_END_IGNORE_DEPRECATIONS
  if (screenshots == NULL || n < 0 || (guint)n >= screenshots->len)
    return NULL;
  return new QSnapdScreenshot(screenshots->pdata[n]);
}

QSnapdEnums::SnapType QSnapdSnap::snapType() const {
  switch (snapd_snap_get_snap_type(SNAPD_SNAP(wrapped_object))) {
  case SNAPD_SNAP_TYPE_APP:
    return QSnapdEnums::SnapTypeApp;
  case SNAPD_SNAP_TYPE_KERNEL:
    return QSnapdEnums::SnapTypeKernel;
  case SNAPD_SNAP_TYPE_GADGET:
    return QSnapdEnums::SnapTypeGadget;
  case SNAPD_SNAP_TYPE_OS:
    return QSnapdEnums::SnapTypeOperatingSystem;
  case SNAPD_SNAP_TYPE_CORE:
    return QSnapdEnums::SnapTypeCore;
  case SNAPD_SNAP_TYPE_BASE:
    return QSnapdEnums::SnapTypeBase;
  case SNAPD_SNAP_TYPE_SNAPD:
    return QSnapdEnums::SnapTypeSnapd;
  case SNAPD_SNAP_TYPE_UNKNOWN:
  default:
    return QSnapdEnums::SnapTypeUnknown;
  }
}

QSnapdEnums::SnapStatus QSnapdSnap::status() const {
  switch (snapd_snap_get_status(SNAPD_SNAP(wrapped_object))) {
  case SNAPD_SNAP_STATUS_AVAILABLE:
    return QSnapdEnums::SnapStatusAvailable;
  case SNAPD_SNAP_STATUS_PRICED:
    return QSnapdEnums::SnapStatusPriced;
  case SNAPD_SNAP_STATUS_INSTALLED:
    return QSnapdEnums::SnapStatusInstalled;
  case SNAPD_SNAP_STATUS_ACTIVE:
    return QSnapdEnums::SnapStatusActive;
  case SNAPD_SNAP_STATUS_UNKNOWN:
  default:
    return QSnapdEnums::SnapStatusUnknown;
  }
}

QString QSnapdSnap::storeUrl() const {
  return snapd_snap_get_store_url(SNAPD_SNAP(wrapped_object));
}

QString QSnapdSnap::summary() const {
  return snapd_snap_get_summary(SNAPD_SNAP(wrapped_object));
}

QString QSnapdSnap::title() const {
  return snapd_snap_get_title(SNAPD_SNAP(wrapped_object));
}

QString QSnapdSnap::trackingChannel() const {
  return snapd_snap_get_tracking_channel(SNAPD_SNAP(wrapped_object));
}

QStringList QSnapdSnap::tracks() const {
  GStrv tracks = snapd_snap_get_tracks(SNAPD_SNAP(wrapped_object));
  QStringList result;
  for (int i = 0; tracks[i] != NULL; i++)
    result.append(tracks[i]);
  return result;
}

bool QSnapdSnap::trymode() const {
  return snapd_snap_get_trymode(SNAPD_SNAP(wrapped_object));
}

QString QSnapdSnap::version() const {
  return snapd_snap_get_version(SNAPD_SNAP(wrapped_object));
}

QString QSnapdSnap::website() const {
  return snapd_snap_get_website(SNAPD_SNAP(wrapped_object));
}
