const fs        = require('fs');
const path      = require('path');
const Events    = require('../../models/events');
const utils     = require('../../utils');
const _         = require('lodash');
const stringify = require('stringify-object');

const distPath   = path.join(__dirname, '../');
const schemaPath = distPath + '/schemas';

const stringifyOptions = {
  indent:       '  ',
  singleQuotes: true
};

const generateFullSchemas = (eventType) => {
  const eventClass = capitalizeFirstLetter(eventType);
  const eventName  = _.camelCase(eventType);

  console.log(`Building full schemas for eventType: ${eventClass}`);

  const schemas = Events[eventClass].getSchemas();

  cleanAndWriteSchemas(schemas, eventName);
};

const generatePartialSchemas = (eventType) => {
  const eventClass = capitalizeFirstLetter(eventType);
  const eventName  = `auto${eventClass}`;

  console.log(`Building partial schemas for eventType: ${eventClass}`);

  const schemas = Events.partials.auto[eventClass].getSchemas();
  cleanAndWriteSchemas(schemas, eventName);
};

const cleanAndWriteSchemas = (schemas, eventName) => {
  // Remove generated validation
  if (eventName !== Events.Invalid.NAME) {
    if (_.has(schemas, 'validation.properties.visit.properties.generated')) {
      delete schemas.validation.properties.visit.properties.generated;
    }
    
    if (_.has(schemas, 'sanitization.properties.visit.properties.generated')) {
      delete schemas.sanitization.properties.visit.properties.generated;
    }
  }

  // Remove these from the invalid event schemas
  delete schemas.validation.properties.dateReceivedAsInvalid;
  delete schemas.sanitization.properties.dateReceivedAsInvalid;

  // Do not require ID field on the event from the browser
  delete schemas.validation.properties.id;
  delete schemas.sanitization.properties.id;

  fs.writeFileSync(`${schemaPath}/${eventName}.js`, `var utils = require('./utils');${'\n'}module.exports=${stringify(schemas, stringifyOptions)}`);
};

const capitalizeFirstLetter = (string) => {
  return string.charAt(0).toUpperCase() + string.slice(1);
};


if (!fs.existsSync(distPath)) {
  fs.mkdirSync(distPath);
}

if (!fs.existsSync(schemaPath)) {
  fs.mkdirSync(schemaPath);
}

// Strip the portions of the schemas that are generated on the backend

const fullEventTypes = [
  'Invalid',
  'AddToCart',
  'ViewCart',
  'RemoveFromCart',
  'Order',
  'Search',
  'SessionChange',
  'ViewProduct'
];

const partialEventTypes = [
  'Search',
  'MoreRefinements'
];

fs.writeFileSync(`${schemaPath}/utils.js`, `module.exports = ${stringify(_.pick(utils, 'regex'), stringifyOptions)};`);
fs.writeFileSync(`${schemaPath}/DO_NOT_TOUCH__ALL_AUTOGENERATED`, `Don't do it.\n\nThese are auto-generated and checked-in by node-common when a release is made.`);

_.forEach(fullEventTypes, generateFullSchemas);
_.forEach(partialEventTypes, generatePartialSchemas);

@@ -2,23 +2,16 @@
 onst fs 
-       
 = requir
@@ -30,21 +30,16 @@
 st path 
-     
 = requir
@@ -62,19 +62,16 @@
  Events 
-   
 = requir
@@ -108,20 +108,16 @@
 t utils 
-    
 = requir
@@ -141,24 +141,16 @@
 %0Aconst _
-        
  = requi
@@ -226,18 +226,16 @@
 istPath 
-  
 = path.j
@@ -276,24 +276,27 @@
 aPath = 
+%60$%7B
 distPath
  + '/sch
@@ -291,20 +291,17 @@
 Path
- + '
+%7D
 /schemas
 ';%0A%0A
@@ -296,17 +296,17 @@
 /schemas
-'
+%60
 ;%0A%0Aconst
@@ -336,22 +336,16 @@
  indent:
-      
  '  ',%0A 
@@ -387,32 +387,54 @@
 ateFullSchemas =
+ (withSanitization) =%3E
  (eventType) =%3E 
@@ -508,17 +508,16 @@
 entName 
- 
 = _.came
@@ -563,16 +563,56 @@
 ing full
+$%7BwithSanitization ? '' : ' validation'%7D
  schemas
@@ -730,32 +730,50 @@
 hemas, eventName
+, withSanitization
 );%0A%7D;%0A%0Aconst gen
@@ -793,16 +793,38 @@
 chemas =
+ (withSanitization) =%3E
  (eventT
@@ -906,17 +906,16 @@
 entName 
- 
 = %60auto$
@@ -961,16 +961,56 @@
  partial
+$%7BwithSanitization ? '' : ' validation'%7D
  schemas
@@ -1149,16 +1149,34 @@
 ventName
+, withSanitization
 );%0A%7D;%0A%0Ac
@@ -1222,16 +1222,34 @@
 ventName
+, withSanitization
 ) =%3E %7B%0A 
@@ -1478,20 +1478,16 @@
 ;%0A    %7D%0A
-    
 %0A    if 
@@ -1750,24 +1750,99 @@
 dAsInvalid;%0A
+  if (_.has(schemas, 'sanitization.properties.dateReceivedAsInvalid')) %7B%0A  
   delete sch
@@ -1892,16 +1892,20 @@
 Invalid;
+%0A  %7D
 %0A%0A  // D
@@ -2006,49 +2006,197 @@
 ;%0A  
-delete schemas.sanitization.properties.id
+if (_.has(schemas, 'sanitization.properties.id')) %7B%0A    delete schemas.sanitization.properties.id;%0A  %7D%0A%0A  const finalSchema = withSanitization ? schemas : %7B validation: schemas.validation %7D
 ;%0A%0A 
@@ -2240,16 +2240,54 @@
 entName%7D
+$%7BwithSanitization ? '' : '-validate'%7D
 .js%60, %60v
@@ -2350,23 +2350,27 @@
 ringify(
-s
+finalS
 chema
-s
 , string
@@ -3243,61 +3243,189 @@
 emas
-);%0A_.forEach(partialEventTypes, generatePartialSchemas
+(true));%0A_.forEach(fullEventTypes, generateFullSchemas(false));%0A_.forEach(partialEventTypes, generatePartialSchemas(true));%0A_.forEach(partialEventTypes, generatePartialSchemas(false)
 );%0A

build both validation-only and full schemas (#23)