/*
 * This file is part of the Polkit-tqt project
 * Copyright (C) 2009 Lukas Tinkl <ltinkl@redhat.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB. If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <polkit/polkit.h>

#include "polkit-tqt-identity.h"

#include <tqshared.h>
#include <tqstring.h>


namespace PolkitTQt
{

//--------------------------------------
// Identity::Data
//--------------------------------------

class Identity::Data : public TQShared
{
  public:
    Data() : identity(nullptr)
    {
    }

    Data(const Data &other) : identity(other.identity)
    {
      if (identity)
      {
        g_object_ref(identity);
      }
    }

    Data(PolkitIdentity *_identity) : identity(_identity)
    {
      if (identity)
      {
        g_object_ref(identity);
      }
    }

    ~Data()
    {
      if (identity)
      {
        g_object_unref(identity);
      }
    }

    PolkitIdentity *identity;
};

//--------------------------------------
// Identity
//--------------------------------------

Identity::Identity() : d(new Data)
{
}

Identity::Identity(PolkitIdentity *pkIdentity) : d(new Data(pkIdentity))
{
}

Identity::Identity(const Identity &other) : d(other.d)
{
  d->ref();
}

Identity& Identity::operator=(const Identity &other)
{
  if (d != other.d)
  {
    if (d->deref())
    {
      delete d;
    }
    d = other.d;
    d->ref();
  }
  return *this;
}

Identity::~Identity()
{
  if (d->deref())
  {
    delete d;
  }
}

bool Identity::isValid() const
{
  return (d->identity != nullptr);
}

PolkitIdentity* Identity::identity() const
{
  return d->identity;
}

void Identity::setIdentity(PolkitIdentity *identity)
{
  if (d->identity != identity)
  {
    if (d->identity)
    {
      g_object_unref(d->identity);
    }
    d->identity = identity;
    if (d->identity)
    {
      g_object_ref(d->identity);
    }
  }
}

TQString Identity::toString() const
{
  if (!d->identity)
  {
    return TQString::null;
  }
  return TQString::fromUtf8(polkit_identity_to_string(d->identity));
}

Identity Identity::fromString(const TQString &string)
{
  if (string.isEmpty())
  {
    tqWarning(TQString("Cannot create valid Identity from empty string."));
    return Identity();
  }

  GError *error = nullptr;
  PolkitIdentity *poliden = polkit_identity_from_string(string.utf8().data(), &error);
  if (error != nullptr)
  {
    tqWarning(TQString("Cannot create valid Identity from string: %1").arg(error->message));
    return Identity();
  }

  return Identity(poliden);
}

//--------------------------------------
// UnixUserIdentity
//--------------------------------------

UnixUserIdentity::UnixUserIdentity(const TQString &name) : Identity()
{
  GError *error = nullptr;
  setIdentity(polkit_unix_user_new_for_name(name.utf8().data(), &error));
  if (error != nullptr)
  {
    tqWarning(TQString("Cannot create UnixUserIdentity: %1").arg(error->message));
    setIdentity(nullptr);
  }
}

UnixUserIdentity::UnixUserIdentity(uid_t uid) : Identity()
{
  setIdentity(polkit_unix_user_new(uid));
}

UnixUserIdentity::UnixUserIdentity(PolkitUnixUser *pkUnixUser)
        : Identity((PolkitIdentity*)pkUnixUser)
{
}

uid_t UnixUserIdentity::uid() const
{
  return polkit_unix_user_get_uid((PolkitUnixUser*)identity());
}

void UnixUserIdentity::setUid(uid_t uid)
{
  polkit_unix_user_set_uid((PolkitUnixUser*)identity(), uid);
}

//--------------------------------------
// UnixGroupIdentity
//--------------------------------------

UnixGroupIdentity::UnixGroupIdentity(const TQString &name) : Identity()
{
  GError *error = nullptr;
  setIdentity(polkit_unix_group_new_for_name(name.utf8().data(), &error));
  if (error != nullptr)
  {
    tqWarning(TQString("Cannot create UnixGroupIdentity: %1").arg(error->message));
    setIdentity(nullptr);
  }
}

UnixGroupIdentity::UnixGroupIdentity(gid_t gid) : Identity()
{
  setIdentity(polkit_unix_group_new(gid));
}

UnixGroupIdentity::UnixGroupIdentity(PolkitUnixGroup *pkUnixGroup)
        : Identity((PolkitIdentity*)pkUnixGroup)
{
}

gid_t UnixGroupIdentity::gid() const
{
  return polkit_unix_group_get_gid((PolkitUnixGroup*)identity());
}

void UnixGroupIdentity::setGid(gid_t gid)
{
  polkit_unix_group_set_gid((PolkitUnixGroup*)identity(), gid);
}

}
