text: 'use strict';
  
  function Client(serverPath) {
  
    const ParsePath = (requestPath) => {
  
      let reqPath;
  
      if (requestPath) {
        reqPath = requestPath.toString();
      } else {
        reqPath = '/';
      }
  
      let parts = reqPath.toString()
        .replace(/\/\//g, '/')
        .replace(/^\//, '')
        .replace(/\/$/, '')
        .replace(/\/\//g, '/')
        .split('/');
  
      let channel = '/' + parts.slice(0, -1).join('/');
      let key = parts.slice(-1)[0];
      let slash = "";
      if (channel !== '/') {
        slash = '/';
      }
      let path = channel + slash + key;
  
      let dsPath = '!' + channel + '!' + key;
  
      return {
        "path": path,
        "channel": channel,
        "key": key,
        "slash": slash,
        "dsPath": dsPath
      };
    };
  
  
    let token = null;
    let tokenHandler = null;
  
    let channels = {};
  
    const request = async (req) => {
      return new Promise(async (resolve,reject) => {
  
        if (tokenHandler && typeof tokenHandler === 'function') {
          token = await tokenHandler();
        } 
  
        let body = {};
        body.path = req.path || null;
        body.method = req.method || null;
        body.data = req.data || null;
        body.token = req.token || token || null;
  
        const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));
  
        return fetch(serverPath,{
          "method":"POST",
          "headers":{
            "content-type":"application/json"
          },
          "body":JSON.stringify(body)
        }).then(async response=>{
          return resolve(await response.json());
        }).catch((err)=>{
          if (err) {
            return reject({"code":400, "message":err.message||err.toString()||"Error!"});
          } else {
            return reject({"code":400,"message":"Error!"});
          }
        });
      });
    };
  
    const setToken = (newToken) => {
      token = newToken;
      return true;
    };
  
    const setTokenHandler = (cb) => {
      tokenHandler = cb;
      return true;
    };
  
    const Put = (path,data) => {
      return request({"method":"put","path":path,"data":data});
    };
  
    const Get = (path,query) => {
      return request({"method":"get","path":path, "data":query});
    };
  
    const Del = (path) => {
      return request({"method":"del","path":path});
    };
  
    const List = (path,data) => {
      return request({"method":"list","path":path,"data":data});
    };
  
    const Channel = (requestPath) => {
  
      let parsed = ParsePath(requestPath);
      let parsedPath = parsed.path;
  
      let chan = {
  
        "channel": () => {
          return parsedPath;
        },
  
        "setToken": (token) => {
          setToken(token);
        },
  
        "setTokenHandler": (cb) => {
          setTokenHandler(cb);
        },
  
        "request": (req) => {
          return request({"method":req.method||null,"path":req.path||parsedPath,"data":req.data||null,"token":req.token||null});
        },
  
        "put": (data) => {
          return Put(parsedPath, data);
        },
  
        "get": (query) => {
          return Get(parsedPath,query);
        },
  
        "del": () => {
          return Del(parsedPath);
        },
  
        "list": (query) => {
          return List(parsedPath, query);
        },
  
        "parse": (path=null) => {
          return ParsePath((path||parsedPath).toString());
        },
  
        "path": (path) => {
          if (!path) {
            path = "/";
          }
          let slash = "";
          if (parsedPath !== '/') {
            slash = "/";
          }
          return Channel(parsedPath + slash + path);
        },
  
      };
  
      return chan;
  
    };
  
    return Channel('/');
  
  }
  
  module.exports = Client;
  