//-----------------------------------------------
//V 1.10
//  04/26.2023
//  add script lock and check
//  add customer field parse to column process
//
//V 1.00
//  2018
//-----------------------------------------------

// Format a string into text for the HTML response

function out(s) {
  return ContentService.createTextOutput(s).setMimeType(ContentService.MimeType.TEXT);
}

function doPost(e) {
  //  Logger.clear();

  var ssID = ScriptProperties.getProperty('targetSpreadsheetID');
  if (ssID == null) {
    return (out("Property targetSpreadsheetID not found. Be sure to run Setup script."));
  }

  //  Logger.log("Spreadsheet ID=%s", ssID );  

  var lock = LockService.getScriptLock();
  try {
    lock.waitLock(30000);
  } catch (ex) {
    Logger.log('Could not obtain lock after 30 seconds.');
    return HtmlService.createHtmlOutput("<b> Server Busy please try after some time <p>")
    // In case this a server side code called asynchronously you return a error code and display the appropriate message on the client side
    return "Error: Google Server busy. Try again later... "
  }

  var ss = SpreadsheetApp.openById(ssID);

  if (ss == null) {
    lock.releaseLock();
    return (out("Could not find spreadsheet ID [" + ssID + "]. Aborting."));
  }

  var sheetName = ScriptProperties.getProperty('targetSheetName');
  if (sheetName == null) {
    lock.releaseLock();
    return (out("Property targetSheetName not found. Be sure to run Setup script."));
  }

  //  Logger.log( "Target Sheet Name=%s" , sheetName );  

  var sheet = ss.getSheetByName(sheetName);

  // No such thing as Spreadsheet.getSheetById()? Really?

  if (sheet == null) {
    lock.releaseLock();
    return (out("Could not find sheet named  [" + sheetName + "]. Aborting."));
  }

  var parameters = e.parameter;   // Grab the  parameters from the request

  var headers;

  if (sheet.getLastColumn() == 0) {   // Special case of empty sheet...
    headers = [];
  } else {
    headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];  //read headers from top row of spreadsheet    
  }

  var newHeadersFlag = false;

  var newRow = [];     // Hold new row to be Added to bottom

  // loop through the request parameter names (keys) and 
  // put them in the right column in spreadsheet
  for (var p in parameters) {
    //    Logger.log( " parameter key=%s"  ,  p );

    var col = headers.indexOf(p);    // Find column for the param name 

    if (p != "Custom Fields") {
      if (col < 0) {  // if matching col header not found

        // add new column at end           
        headers.push(p);
        col = headers.indexOf(p);    // Find column for the param name       
        newHeadersFlag = true;

        //      Logger.log( "New col=%s" ,  col );

        // Note that it appears if you send multipule params with 
        // the same name that only the first one shows up

      }

      // Lookup value of the passed param and put it into the new row we are building
      newRow[col] = parameters[p];
      //    Logger.log( " col=%s value=%s", col  , newRow[col] );

    } else {
      //custom field
      var cfstr = parameters[p];
      Logger.log("cfstr=%s", cfstr);

      if (cfstr != null && cfstr.length >= 2) {
        var cfsss = cfstr.split(",");
        for (var i in cfsss) {
          if (cfsss[i].length >= 2 && cfsss[i].indexOf(":") != -1) {
            var cfss = cfsss[i].split(":");
            Logger.log("%s %s", cfss[0], cfss[1]);

            var colcf = headers.indexOf(cfss[0]);    // Find column for the param name 
            if (colcf < 0) {  // if matching col header not found
              // add new column at end           
              headers.push(cfss[0]);
              colcf = headers.indexOf(cfss[0]);    // Find column for the param name       
              newHeadersFlag = true;
              //Logger.log( "New col=%s" ,  col );
            }
            newRow[colcf] = cfss[1];
          } else {
            var cfvalue = cfsss[i].replace(/^\s+|\s+$/gm, '');  //trim(), remove all leading and ending spaces
            if (cfvalue.length >= 1) {
              var cflabel = "Field " + (+i + 1).toString();
              Logger.log("%s  %s", cflabel, cfvalue);

              var colcf = headers.indexOf(cflabel);    // Find column for the param name 
              if (colcf < 0) {  // if matching col header not found
                // add new column at end           
                headers.push(cflabel);
                colcf = headers.indexOf(cflabel);    // Find column for the param name       
                newHeadersFlag = true;
                //Logger.log( "New col=%s" ,  col );
              }
              newRow[colcf] = cfvalue;
            }
          }
        }
      }
    }
  }

  // Necessary because appending a blank row causes a 
  // Sheet Serivce Error after the script completes
  if (newRow.length == 0) {
    return (out("No parameters found, no data appended."));
  }

  if (newHeadersFlag) {   // We updated some headers, so reflect in the sheet
    var headersRange = [headers]; // Must be 2 dimensional array to set a range
    sheet.getRange(1, 1, 1, headers.length).setValues(headersRange);
  }

  sheet.appendRow(newRow);   // Append new row to end of spreadsheet  
  return (out("Data appended successfully."));

}

function doGet(e) {
  return (doPost(e));
}

function setupLoggingToCurrentSheet() {
  ScriptProperties.setProperty('targetSpreadsheetID', SpreadsheetApp.getActiveSpreadsheet().getId());
  ScriptProperties.setProperty('targetSheetName', SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getSheetName());
}

function clearLog() {
  var spreadsheet = SpreadsheetApp.getActive();
  var last = SpreadsheetApp.getActiveSheet().getLastRow();
  spreadsheet.deleteRows(2, last - 1);
}

function onOpen() {
  SpreadsheetApp.getActive()
    .addMenu("V9 Script",
      [{ name: "Active log", functionName: "setupLoggingToCurrentSheet" },
      { name: "Clear log", functionName: "clearLog" }]);
}