/*---------------------------------------------------------------------\
|                          ____ _   __ __ ___                          |
|                         |__  / \ / / . \ . \                         |
|                           / / \ V /|  _/  _/                         |
|                          / /__ | | | | | |                           |
|                         /_____||_| |_| |_|                           |
|                                                                      |
\---------------------------------------------------------------------*/
/** \file       zypp/repo/RepoInfoBase.cc
 *
 */
#include <iostream>
#include <optional>

#include <zypp/ZConfig.h>
#include <zypp/repo/RepoVariables.h>

#include <zypp/repo/RepoInfoBase.h>
#include <zypp-core/Pathname.h>

using std::endl;

///////////////////////////////////////////////////////////////////
namespace zypp
{
  ///////////////////////////////////////////////////////////////////
  namespace repo
  {

  ///////////////////////////////////////////////////////////////////
  /// \class RepoInfoBase::Impl
  /// \brief RepoInfoBase data
  ///////////////////////////////////////////////////////////////////
  struct RepoInfoBase::Impl
  {
    Impl()
    {}

    Impl( const std::string & alias_r )
    { setAlias( alias_r ); }

  public:
    bool	_enabled     = true;
    bool	_autorefresh = false;
    std::string	_alias;
    std::optional<std::string> _escaped_alias;
    RepoVariablesReplacedString _name;
    Pathname	_filepath;

  public:

    void setAlias( const std::string & alias_r )
    {
      _alias = alias_r;
      if ( _alias.find( "/" ) != std::string::npos ) {
      // replace slashes with underscores
        _escaped_alias = _alias;
        str::replaceAll( *_escaped_alias, "/", "_" );
      } else {
        _escaped_alias.reset();
      }
    }

  private:
    friend Impl * rwcowClone<Impl>( const Impl * rhs );
    /** clone for RWCOW_pointer */
    Impl * clone() const
    { return new Impl( *this ); }
  };
  ///////////////////////////////////////////////////////////////////

  ///////////////////////////////////////////////////////////////////
  //
  //    CLASS NAME : RepoInfoBase
  //
  ///////////////////////////////////////////////////////////////////

  RepoInfoBase::RepoInfoBase()
    : _pimpl( new Impl() )
  {}

  RepoInfoBase::RepoInfoBase(const std::string & alias)
    : _pimpl( new Impl(alias) )
  {}

  RepoInfoBase::~RepoInfoBase()
  {}

  void RepoInfoBase::setEnabled( bool enabled )
  { _pimpl->_enabled = enabled; }

  void RepoInfoBase::setAutorefresh( bool autorefresh )
  { _pimpl->_autorefresh = autorefresh; }

  void RepoInfoBase::setAlias( const std::string &alias )
  { _pimpl->setAlias(alias); }

  void RepoInfoBase::setName( const std::string &name )
  { _pimpl->_name.raw() = name; }

  void RepoInfoBase::setFilepath( const Pathname &filepath )
  { _pimpl->_filepath = filepath; }

  bool RepoInfoBase::enabled() const
  { return _pimpl->_enabled; }

  bool RepoInfoBase::autorefresh() const
  { return _pimpl->_autorefresh; }

  std::string RepoInfoBase::alias() const
  { return _pimpl->_alias; }

  std::string RepoInfoBase::escaped_alias() const
  { return _pimpl->_escaped_alias ? *_pimpl->_escaped_alias : _pimpl->_alias; }

  std::string RepoInfoBase::name() const
  {
    if ( rawName().empty() )
      return alias();
    return repo::RepoVariablesStringReplacer()( rawName() );
  }

  std::string RepoInfoBase::rawName() const
  { return _pimpl->_name.raw(); }

  std::string RepoInfoBase::label() const
  {
    if ( ZConfig::instance().repoLabelIsAlias() )
      return alias();
    return name();
  }

  Pathname RepoInfoBase::filepath() const
  { return _pimpl->_filepath; }


  std::ostream & RepoInfoBase::dumpOn( std::ostream & str ) const
  {
    str << "--------------------------------------" << std::endl;
    str << "- alias       : " << alias() << std::endl;
    if ( ! rawName().empty() )
      str << "- name        : " << rawName() << std::endl;
    str << "- enabled     : " << enabled() << std::endl;
    str << "- autorefresh : " << autorefresh() << std::endl;

    return str;
  }

  std::ostream & RepoInfoBase::dumpAsIniOn( std::ostream & str ) const
  {
    // we save the original data without variable replacement
    str << "[" << alias() << "]" << endl;
    if ( ! rawName().empty() )
      str << "name=" << rawName() << endl;
    str << "enabled=" << (enabled() ? "1" : "0") << endl;
    str << "autorefresh=" << (autorefresh() ? "1" : "0") << endl;

    return str;
  }

  std::ostream & RepoInfoBase::dumpAsXmlOn( std::ostream & str, const std::string & content ) const
  {
    return str << "<!-- there's no XML representation of RepoInfoBase -->" << endl;
  }

  std::ostream & operator<<( std::ostream & str, const RepoInfoBase & obj )
  {
    return obj.dumpOn(str);
  }

  } // namespace repo
  ///////////////////////////////////////////////////////////////////
} // namespace zypp
///////////////////////////////////////////////////////////////////
