// @(#)root/net:$Id$
// Author: G. Ganis Feb 2011

/*************************************************************************
 * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TNetFileStager                                                       //
//                                                                      //
// TFileStager implementation for a 'rootd' backend.                    //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TError.h"
#include "TObjString.h"
#include "TUrl.h"
#include "TNetFile.h"
#include "TNetFileStager.h"

//_____________________________________________________________________________
TNetFileStager::TNetFileStager(const char *url) : TFileStager("net")
{
   // Constructor. Init a TNetSystem instance to the remote rootd.

   fSystem = 0;
   if (url && strlen(url) > 0) {
      GetPrefix(url, fPrefix);

      fSystem = new TNetSystem(fPrefix);
   }
}

//_____________________________________________________________________________
TNetFileStager::~TNetFileStager()
{
   // Destructor

   SafeDelete(fSystem);
   fPrefix = "";
}

//_____________________________________________________________________________
Bool_t TNetFileStager::IsStaged(const char *path)
{
   // Check if the file defined by 'path' is ready to be used.

   if (!IsValid()) {
      GetPrefix(path, fPrefix);
      fSystem = new TNetSystem(path);
   }

   if (IsValid()) {
      TString p(path);
      if (!p.BeginsWith(fPrefix)) p.Insert(0, fPrefix);
      return (fSystem->AccessPathName(p, kReadPermission) ? kFALSE : kTRUE);
   }

   // Failure
   Warning("IsStaged","TNetSystem not initialized");
   return kFALSE;
}

//_____________________________________________________________________________
void TNetFileStager::GetPrefix(const char *url, TString &pfx)
{
   // Isolate prefix in url

   if (gDebug > 1)
      ::Info("TNetFileStager::GetPrefix", "enter: %s", url);

   TUrl u(url);
   pfx = TString::Format("%s://", u.GetProtocol());
   if (strlen(u.GetUser()) > 0)
      pfx += TString::Format("%s@", u.GetUser());
   pfx += u.GetHost();
   if (u.GetPort() != TUrl("root://host").GetPort())
      pfx += TString::Format(":%d", u.GetPort());
   pfx += "/";

   if (gDebug > 1)
      ::Info("TNetFileStager::GetPrefix", "found prefix: %s", pfx.Data());
}

//_____________________________________________________________________________
void TNetFileStager::Print(Option_t *) const
{
   // Print basic info about this stager

   Printf("+++ stager: %s  %s", GetName(), fPrefix.Data());
}

//______________________________________________________________________________
Int_t TNetFileStager::Locate(const char *path, TString &eurl)
{
   // Get actual end-point url for a path
   // Returns 0 in case of success and 1 if any error occured

   if (!IsValid()) {
      GetPrefix(path, fPrefix);
      fSystem = new TNetSystem(path);
   }

   if (IsValid()) {
      TString p(path);
      if (!p.BeginsWith(fPrefix)) p.Insert(0, fPrefix);
      if (!fSystem->AccessPathName(p, kReadPermission)) {
         eurl = p;
         return 0;
      }
   }

   // Unable to initialize TNetSystem or file does not exist
   return -1;
}

//______________________________________________________________________________
Bool_t TNetFileStager::Matches(const char *s)
{
   // Returns kTRUE if stager 's' is compatible with current stager.
   // Avoids multiple instantiations of the potentially the same TNetSystem.

   if (IsValid()) {
      TString pfx;
      GetPrefix(s, pfx);
      return ((fPrefix == pfx) ? kTRUE : kFALSE);
   }

   // Not valid
   return kFALSE;
}
 TNetFileStager.cxx:1
 TNetFileStager.cxx:2
 TNetFileStager.cxx:3
 TNetFileStager.cxx:4
 TNetFileStager.cxx:5
 TNetFileStager.cxx:6
 TNetFileStager.cxx:7
 TNetFileStager.cxx:8
 TNetFileStager.cxx:9
 TNetFileStager.cxx:10
 TNetFileStager.cxx:11
 TNetFileStager.cxx:12
 TNetFileStager.cxx:13
 TNetFileStager.cxx:14
 TNetFileStager.cxx:15
 TNetFileStager.cxx:16
 TNetFileStager.cxx:17
 TNetFileStager.cxx:18
 TNetFileStager.cxx:19
 TNetFileStager.cxx:20
 TNetFileStager.cxx:21
 TNetFileStager.cxx:22
 TNetFileStager.cxx:23
 TNetFileStager.cxx:24
 TNetFileStager.cxx:25
 TNetFileStager.cxx:26
 TNetFileStager.cxx:27
 TNetFileStager.cxx:28
 TNetFileStager.cxx:29
 TNetFileStager.cxx:30
 TNetFileStager.cxx:31
 TNetFileStager.cxx:32
 TNetFileStager.cxx:33
 TNetFileStager.cxx:34
 TNetFileStager.cxx:35
 TNetFileStager.cxx:36
 TNetFileStager.cxx:37
 TNetFileStager.cxx:38
 TNetFileStager.cxx:39
 TNetFileStager.cxx:40
 TNetFileStager.cxx:41
 TNetFileStager.cxx:42
 TNetFileStager.cxx:43
 TNetFileStager.cxx:44
 TNetFileStager.cxx:45
 TNetFileStager.cxx:46
 TNetFileStager.cxx:47
 TNetFileStager.cxx:48
 TNetFileStager.cxx:49
 TNetFileStager.cxx:50
 TNetFileStager.cxx:51
 TNetFileStager.cxx:52
 TNetFileStager.cxx:53
 TNetFileStager.cxx:54
 TNetFileStager.cxx:55
 TNetFileStager.cxx:56
 TNetFileStager.cxx:57
 TNetFileStager.cxx:58
 TNetFileStager.cxx:59
 TNetFileStager.cxx:60
 TNetFileStager.cxx:61
 TNetFileStager.cxx:62
 TNetFileStager.cxx:63
 TNetFileStager.cxx:64
 TNetFileStager.cxx:65
 TNetFileStager.cxx:66
 TNetFileStager.cxx:67
 TNetFileStager.cxx:68
 TNetFileStager.cxx:69
 TNetFileStager.cxx:70
 TNetFileStager.cxx:71
 TNetFileStager.cxx:72
 TNetFileStager.cxx:73
 TNetFileStager.cxx:74
 TNetFileStager.cxx:75
 TNetFileStager.cxx:76
 TNetFileStager.cxx:77
 TNetFileStager.cxx:78
 TNetFileStager.cxx:79
 TNetFileStager.cxx:80
 TNetFileStager.cxx:81
 TNetFileStager.cxx:82
 TNetFileStager.cxx:83
 TNetFileStager.cxx:84
 TNetFileStager.cxx:85
 TNetFileStager.cxx:86
 TNetFileStager.cxx:87
 TNetFileStager.cxx:88
 TNetFileStager.cxx:89
 TNetFileStager.cxx:90
 TNetFileStager.cxx:91
 TNetFileStager.cxx:92
 TNetFileStager.cxx:93
 TNetFileStager.cxx:94
 TNetFileStager.cxx:95
 TNetFileStager.cxx:96
 TNetFileStager.cxx:97
 TNetFileStager.cxx:98
 TNetFileStager.cxx:99
 TNetFileStager.cxx:100
 TNetFileStager.cxx:101
 TNetFileStager.cxx:102
 TNetFileStager.cxx:103
 TNetFileStager.cxx:104
 TNetFileStager.cxx:105
 TNetFileStager.cxx:106
 TNetFileStager.cxx:107
 TNetFileStager.cxx:108
 TNetFileStager.cxx:109
 TNetFileStager.cxx:110
 TNetFileStager.cxx:111
 TNetFileStager.cxx:112
 TNetFileStager.cxx:113
 TNetFileStager.cxx:114
 TNetFileStager.cxx:115
 TNetFileStager.cxx:116
 TNetFileStager.cxx:117
 TNetFileStager.cxx:118
 TNetFileStager.cxx:119
 TNetFileStager.cxx:120
 TNetFileStager.cxx:121
 TNetFileStager.cxx:122
 TNetFileStager.cxx:123
 TNetFileStager.cxx:124
 TNetFileStager.cxx:125
 TNetFileStager.cxx:126
 TNetFileStager.cxx:127
 TNetFileStager.cxx:128
 TNetFileStager.cxx:129
 TNetFileStager.cxx:130
 TNetFileStager.cxx:131
 TNetFileStager.cxx:132
 TNetFileStager.cxx:133
 TNetFileStager.cxx:134
 TNetFileStager.cxx:135
 TNetFileStager.cxx:136