text: /////////////////////////////////////////////////////////////////////
  // Copyright (c) Autodesk, Inc. All rights reserved
  // Written by Forge Partner Development
  //
  // Permission to use, copy, modify, and distribute this software in
  // object code form for any purpose and without fee is hereby granted,
  // provided that the above copyright notice appears in all copies and
  // that both that copyright notice and the limited warranty and
  // restricted rights notice below appear in all supporting
  // documentation.
  //
  // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
  // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
  // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC.
  // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
  // UNINTERRUPTED OR ERROR FREE.
  /////////////////////////////////////////////////////////////////////
  const axios=require('axios');
  var XLSX = require('xlsx')
  const express = require('express');
  const { HubsApi, ProjectsApi, FoldersApi, ItemsApi } = require('forge-apis');
  
  const { OAuth } = require('./common/oauth');
  
  let router = express.Router();
  
  router.get('/datamanagement', async (req, res) => {
      // The id querystring parameter contains what was selected on the UI tree, make sure it's valid
      const href = decodeURIComponent(req.query.id);
      if (href === '') {
          res.status(500).end();
          return;
      }
  
      // Get the access token
      const oauth = new OAuth(req.session);
      const internalToken = await oauth.getInternalToken();
     // console.log(internalToken);
      if (href === '#') {
          // If href is '#', it's the root tree node
          getHubs(oauth.getClient(), internalToken, res);
      } else {
          // Otherwise let's break it by '/'
          const params = href.split('/');
          const resourceName = params[params.length - 2];
          const resourceId = params[params.length - 1];
          switch (resourceName) {
              case 'hubs':
                  getProjects(resourceId, oauth.getClient(), internalToken, res);
                  break;
              case 'projects':
                  // For a project, first we need the top/root folder
                  const hubId = params[params.length - 3];
                  getFolders(hubId, resourceId/*project_id*/, oauth.getClient(), internalToken, res);
                  break;
              case 'folders':
                  {
                      const projectId = params[params.length - 3];
                      getFolderContents(projectId, resourceId/*folder_id*/, oauth.getClient(), internalToken, res);
                      break;
                  }
              case 'items':
                  {
                      const projectId = params[params.length - 3];
                      getVersions(projectId, resourceId/*item_id*/, oauth.getClient(), internalToken, res);
                      break;
                  }
          }
      }
  });
  
  async function getHubs(oauthClient, credentials, res) {
      const hubs = new HubsApi();
      const data = await hubs.getHubs({}, oauthClient, credentials);
      res.json(data.body.data.map((hub) => {
          let hubType;
          switch (hub.attributes.extension.type) {
              case 'hubs:autodesk.core:Hub':
                  hubType = 'hubs';
                  break;
              case 'hubs:autodesk.a360:PersonalHub':
                  hubType = 'personalHub';
                  break;
              case 'hubs:autodesk.bim360:Account':
                  hubType = 'bim360Hubs';
                  break;
          }
          return createTreeNode(
              hub.links.self.href,
              hub.attributes.name,
              hubType,
              true
          );
      }));
  }
  
  async function getProjects(hubId, oauthClient, credentials, res) {
      const projects = new ProjectsApi();
      const data = await projects.getHubProjects(hubId, {}, oauthClient, credentials);
      res.json(data.body.data.map((project) => {
          let projectType = 'projects';
          switch (project.attributes.extension.type) {
              case 'projects:autodesk.core:Project':
                  projectType = 'a360projects';
                  break;
              case 'projects:autodesk.bim360:Project':
                  projectType = 'bim360projects';
                  break;
          }
          return createTreeNode(
              project.links.self.href,
              project.attributes.name,
              projectType,
              true
          );
      }));
  }
  
  async function getFolders(hubId, projectId, oauthClient, credentials, res) {
      const projects = new ProjectsApi();
      const folders = await projects.getProjectTopFolders(hubId, projectId, oauthClient, credentials);
      res.json(folders.body.data.map((item) => {
          return createTreeNode(
              item.links.self.href,
              item.attributes.displayName == null ? item.attributes.name : item.attributes.displayName,
              item.type,
              true
          );
      }));
  }
  
  async function getFolderContents(projectId, folderId, oauthClient, credentials, res) {
      const folders = new FoldersApi();
      const contents = await folders.getFolderContents(projectId, folderId, {}, oauthClient, credentials);
      const treeNodes = contents.body.data.map((item) => {
          var name = (item.attributes.name == null ? item.attributes.displayName : item.attributes.name);
          if (name !== '') { // BIM 360 Items with no displayName also don't have storage, so not file to transfer
              //console.log(item.attributes.extension);
              return createTreeNode(
                  item.links.self.href,
                  name,
                  item.type,
                  true
                  
              );
          } else {
              return null;
          }
      });
      res.json(treeNodes.filter(node => node !== null));
  }
  
  async function getVersions(projectId, itemId, oauthClient, credentials, res) {
      const items = new ItemsApi();
      const versions = await items.getItemVersions(projectId, itemId, {}, oauthClient, credentials);
      //console.log(versions.body.data);
      res.json(versions.body.data.map((version) => {
          //console.log(version.attributes.fileType)
          const dateFormated = new Date(version.attributes.lastModifiedTime).toLocaleString();
          const versionst = version.id.match(/^(.*)\?version=(\d+)$/)[2];
          const viewerUrn = (version.relationships != null && version.relationships.derivatives != null ? version.relationships.derivatives.data.id : null);
          const versionID=version.id;
         
          //console.log(version);
          return createTreeNode(
              viewerUrn,
              decodeURI('v' + versionst + ': ' + dateFormated + ' by ' + version.attributes.lastModifiedUserName+ " "+version.attributes.fileType),
              (viewerUrn != null ? 'versions' : 'unsupported'),
              false,
              version.attributes.fileType,
              versionID,
              projectId
              
                     );
      }));
  }
  
  // Format data for tree//el tipo es cosa mia, es la extension del archivo y el project id tambien lo incluyo, pero solo lo relleno con las versiones!!
  function createTreeNode(_id, _text, _type, _children,_tipo,_versionID,_project_id) {
  /*      console.log("***************");
      console.log(_id);
      console.log(_text);
      console.log(_type);
      console.log(_tipo); 
      console.log(_versionID);  */
      return { id: _id, text: _text, type: _type, children: _children,tipo:_tipo,versionID: _versionID, custom:"custom",projectID:_project_id };
  }
  
  router.get('/getExcel', async (req, res) => {
      // The id querystring parameter contains what was selected on the UI tree, make sure it's valid
      console.log('route getExcel');
      
  //console.log(req.query);
  // caracteres NO seguros en la URL, hay que transformarlo escape URL (:.?=) encodeURIComponent
      const project_id = encodeURIComponent(req.query.project_id);
      console.log(project_id)
      //const version_id= decodeURIComponent(req.query.version_id);
      const version_id= encodeURIComponent(req.query.version_id);
  //console.log(project_id);
  //console.log(version_id);
      if (version_id === '') {
          res.status(500).end();
          return;
      }
      
          // Get the access token
          const oauth = new OAuth(req.session);
          const internalToken = await oauth.getInternalToken();
          //************ */
  //para acceder al excel-->obtengo la version y luego res.data.data.relationships.storage...
          const libro1=await axios({//libro 1 contendra el workbook para poder devolverlo
              method: 'get',
              url:`https://developer.api.autodesk.com/data/v1/projects/${project_id}/versions/${version_id}`,
              headers: {
                  'Authorization': `Bearer ${internalToken.access_token}`,
                        },
                      })
          .catch(function(err) {
            /* error in getting data */
            console.log(err)
          })
          
          
          .then(function(res) { 
            //esto es el excel a tratar, donde esta almacenado el archivo de la version
           // console.log(res.data.data.relationships.storage.meta.link.href)
            const excelStorage=res.data.data.relationships.storage.meta.link.href;
            return excelStorage;
          })
          .then(async function (excelStorage){
              //console.log(excelStorage)
                        //tengo que hacer otra peticion para obtener el excel con el link de arriba (excelStorage) y esperando un responsetype arraybuffer
                       const libro=await axios({
                          method: 'get',
                          url:`${excelStorage}`,
                          responseType:'arraybuffer',
                          headers: {
                              'Authorization': `Bearer ${internalToken.access_token}`,
                                    },
                                  })
                                  .then( function(res){
                                      var data = new Uint8Array(res.data);
                                      var workbook = XLSX.read(data, {type:"array"});
                                      return workbook
                                  })
                                  .then(function(workbook) {
                                      /* DO SOMETHING WITH workbook HERE */
                                      //console.log(workbook);
                                      return workbook
                                    })
  
  
  
          return libro;//paso libro al siguiente then(workbook)
          })
          .then(function (workbook){
              //console.log("workbook")
              //console.log(workbook)
  
              return workbook
          })
  
          res.send(libro1)//devuelvo libro 1
  });
  
  //******************************************************************* */
  
  
  module.exports = router;
  