class QueryGrader {

  key_columns
  key_rows
  bookQueryParams
  eventName = 'queryGraderEvent' + Math.random()
  static globalEventName = 'queryGraderEvent'

  /**
   * 
   * @param bookQueryParams 
   */
  constructor(bookQueryParams) {
    this.bookQueryParams = bookQueryParams
  }

  /**
   * Creates a new QueryGrader object with the nessicary params already loaded. 
   * This is to make it easy for us to keep track of which DB types we support.
   * @param {string} db_type 
   * @returns 
   */
  static new(db_type, assessment_data){
    if(db_type === 'oracle'){
      return new QueryGrader({
        engine: db_type,
        connection: assessment_data.connection,
        schema: assessment_data.schema,
      })
    } else if (db_type === 'dataworld'){
      return new QueryGrader({
        engine: db_type,
        schema: assessment_data.schema,
        owner: assessment_data.owner,
        token: BookStorage.dwToken()
      })
    }else if (db_type === 'sqlite') {
      return new QueryGrader({
        schema: assessment_data.schema,
      })
    } else {
      throw new UnableToUseSelectedDBType(db_type)
    }
  }

  dispatch(message){
    document.dispatchEvent( new CustomEvent(this.eventName, {
      detail:{ message }
    }))
    document.dispatchEvent(new CustomEvent(QueryGrader.globalEventName, {
      detail:{ message }
    }))
  }


  /**
   * 
   * @param {[String]} solution_sql_set the correct sql answer(s)
   * @param {String} student_sql the students submitted sql statement to be graded
   * @param {[String] | String} required_terms terms (SELECT, WHERE, JOIN etc) that must be present in the students query
   * @returns graded report
   */
  async grade_query(solution_sql_set, student_sql, required_terms) {

    log("at grade_query", '\n', solution_sql_set, '\n', student_sql, '\n', required_terms)
    const score_card = {
      path: [],
      score: 0,
      stu_sql: student_sql,
      key_sql: solution_sql_set[0]
    }

    // step 1. check to see if we have an exact match with any of our solutions
    if (student_sql.trim() === '') {
      //log("=-----> Query Graded: No Query Found")
      return { zero_credit: true, complexity_index: -1 }
    } else if (this.exact_query_match(student_sql, solution_sql_set)) {
      //log("at exact match")
      score_card.path.push("Student query matched key query")
      score_card.full_credit = true
      score_card.exact_match = true
      score_card.grading_complete = true
      //log("=-----> Query Graded: Exact Match")
      return { full_credit: true, complexity_index: -1, exact_match: true }
    } else {
      //log('there was no exact match, we need to check the student result set against a key result set')
      //there was no exact match, we need to check the student result set against a key result set
      //log("at not exact match",solution_sql_set)

      score_card.key_structure = dwqp.parse(score_card.key_sql) // key_sql is the answer

      // calculate the default partial credit percent cap
      //score_card.element_count = 0

      let structure_count = 0
      let presentation_count = 0
      try{
        structure_count += clause_complexity(score_card.key_structure.from)
        structure_count += clause_complexity(score_card.key_structure.where)
        structure_count += clause_complexity(score_card.key_structure.group)
        structure_count += clause_complexity(score_card.key_structure.having)

        if (score_card.key_structure.limit) structure_count = structure_count + 2

        presentation_count += clause_complexity(score_card.key_structure.select)
        presentation_count += clause_complexity(score_card.key_structure.order)
        score_card.complexity_index = structure_count / (structure_count + presentation_count * 0.5)

      
      }catch(e){
       alert("There was  problem processing the key of this query.  Check the log for the offending key")
       log("================================ Key failed =====================================")
       log(score_card)
       score_card.complexity_index=0
       presentation_count=1
       structure_count=1
      }

      // let element_count=2
      // if(student_sql==='info'){// just log information about key to console then exit
      //log("================================================")
      //log("== Key_sql:", score_card.key_sql)
      //log("== SELECT ======================================")
      //   element_count=element_count+print_clause_components(score_card.key_structure.select)
      //log("== FROM ========================================")
      //   element_count=element_count+print_clause_components(score_card.key_structure.from)
      //log("== WHERE =======================================")
      //   element_count=element_count+print_clause_components(score_card.key_structure.where)
      //log("== GROUP BY ====================================")
      //   element_count=element_count+print_clause_components(score_card.key_structure.group)
      //log("== HAVING ======================================")
      //   element_count=element_count+print_clause_components(score_card.key_structure.having)
      //log("== ORDER BY ====================================")
      //   element_count=element_count+print_clause_components(score_card.key_structure.order)
      //log("== LIMIT =======================================")
      //   if(score_card.key_structure.limit){
      //    log("== present")
      //     element_count++
      //   }
      //log("== Other ======================================")
      //log("== Valid SQL")
      //log("== Correct Column")
      //log("== Other ======================================")
      //log("== total:",element_count)
      //log("== structure_count",structure_count)
      //log("== presentation_count",presentation_count)
      //log("== rci:", Math.round(score_card.complexity_index*100)/100)
      //log("== rci formula:", "structure_count / (structure_count + presentation_count * 0.5)")
      //log("================================================")
      //   return {zero_credit:true,complexity_index:-1}
      // }


      // required terms are values required for a query to execute with the correct answer set.  

      if (required_terms) {
        let terms = []
        if (Array.isArray(required_terms)) {
          terms = required_terms
        } else {
          terms.push(required_terms)
        }

        score_card.missing_terms = []
        for (const term of terms) { //look through the set of supplied terms to see if any are missing
          if (!student_sql.toUpperCase().includes(term.toUpperCase())) {
            score_card.missing_terms.push(term)
          }
        }
        if (score_card.missing_terms.length === 0) { score_card.missing_terms = undefined }

      }

      if (score_card.missing_terms) {  // if the student query is missing required terms, it cannot produce the correct answer set, so there is no reason to execute the query
        score_card.key_ast = sqlParser.parse(score_card.key_sql);
        this.key_columns = this.get_column_names_from_ast(score_card.key_ast)
        this.key_rows = []
        //log("key_ast--->", score_card.key_ast)
      } else {
        await this.grade_one_query(score_card)
      }

      if (score_card.grading_complete) {
        const fb = this.build_feedback_for_correct_record_set(score_card)
        log("=-----> Query Graded: Matched Result Set", fb)
        return fb
      } else {
        // the studet's query result did not match the key restult set
        score_card.path.push("Student query did not match key query")
        // compare student parsed query with each key query to see which gets the best score
        const report_set = []
        for (const one_solution of solution_sql_set) {
          let one_report = { full_credit: false }
          score_card.key_sql = one_solution
          await this.parse_queries(score_card, this.key_columns, this.key_rows)

          //after we have parsed the query, if there are no missing or extra rows, we executed the query with modified select clause.  everything was right except the select clause
          if (!score_card.missing_terms && score_card.rows && score_card.rows.missing === 0 && score_card.rows.extra === 0) {
            const fb = this.build_feedback_for_correct_record_set(score_card)
            log("=-----> Query Graded: Corect except select clause", fb)
            return fb
          }

          // now that we are here, we know that the student's query does not produce the correct result set, so we are working from the ground up to give credit

          one_report.possible = 2 + score_card.partial_credit.length // the two comes from one point for query executed, one point for the right columns
          one_report.earned = score_card.partial_credit_message.length
          one_report.percent = Math.round((one_report.earned / one_report.possible) * 100) / 100
          one_report.feedback = ""
          one_report.error_message = score_card.error_message
          for (const fb of score_card.no_credit_message) {
            one_report.feedback += "" + fb + ". "
          }
          if (one_report.earned === 0) {
            one_report.feedback = "<p>The grader was unable to allocate any partial credit for your solution. " + one_report.feedback + "</p>"
          } else {
            if (score_card.missing_terms) {
              // one report feedback is incorect here becuase it was build without exectuing the student query
              let s = ""
              if (score_card.missing_terms > 1) { s = "s" }
              one_report.feedback = "<p>Your solution does not include the following term" + s + " required to produce the correct result: " + score_card.missing_terms.join()
            } else {
              one_report.feedback = "<p>Your solution was not perfect. " + one_report.feedback
            }

            if (score_card.partial_credit_message.length > 0) {
              one_report.feedback += '</p><font color="black"><p>However, the grader was able to give you some credit as follows: </p>'
              for (const fb of score_card.partial_credit_message) {
                one_report.feedback += "<p>" + fb + ".</p>"
              }
              one_report.feedback += '</font>'
            }
          }

          report_set.push(one_report)
          if (one_report.percent === 100) { break }// can't find a partial credit better than this one
        }
        // now we have evaluated all possible versions of partial credit, just need to pick the highest and retrun it
        log('report set', report_set)
        let high_index = 0
        let high_percent = 0
        for (let x = 1; x < report_set.length; x++) {
          if (report_set[x].percent > high_percent) {
            high_index = x
            high_percent = report_set[x].percent
          }
        }
        report_set[high_index].complexity_index = score_card.complexity_index
        log("=-----> Query Graded: No Exact Match", report_set[high_index])

        return report_set[high_index]
      }


    }


    // functions for use in this function
    function clause_complexity(clause) {// +1 if the clause is used in the query, + 1 for each token in the clause
      let count = 0
      if (Object.keys(clause).length) {
        count = count + .5
        for (const item of Object.values(clause)) count += item.length
      }
      return count
    }
    // function print_clause_components(clause){// +1 if the clause is used in the query, + 1 for each token in the clause
    //   let element_count=0
    //   if(Object.keys(clause).length){
    //     element_count++
    //     for(const item of Object.values(clause)){
    //       for(const one of item){
    //        log("==  ", one)
    //         element_count++
    //       }
    //     }
    //   }
    //   return element_count
    // }

  }

  build_feedback_for_correct_record_set(score_card) {
    // student has as correct rows (perhaps in the wrong order) and may not have the right columns
    let problems = []
    let one_report = {
      full_credit: false,
      correct_records: true,
      full_percent: 1,
      correct_record_order: score_card.rows.correct_order,
      columns_missing: score_card.columns.missing,
      columns_extra: score_card.columns.extra,
      complexity_index: score_card.complexity_index
    }
    //log("at mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm")
    //log("at build_feedback_for_correct_record_set")

    //
    if (!score_card.rows.correct_order) {
      // take away half the residual partial credit for incorrect sort
      one_report.full_percent = one_report.full_percent - 0.5
      problems.push("the records in your result are not in the expected order")
    }

    if (score_card.columns.extra === 1) {
      one_report.full_percent = one_report.full_percent - 0.1
      problems.push("your query has a column that is not requested by the question")
    } else if (score_card.columns.extra > 1) {
      one_report.full_percent = one_report.full_percent - 0.2
      problems.push("your query has " + score_card.columns.extra + " columns that are not requested by the question")
    }

    if (score_card.columns.missing === 1) {
      one_report.full_percent = one_report.full_percent - 0.2
      problems.push("your query is missing a column that is requested by the question")
    } else if (score_card.columns.missing > 1) {
      one_report.full_percent = one_report.full_percent - 0.4
      problems.push("your query is missing " + score_card.columns.missing + " columns that are requested by the question")
    }

    if (problems.length === 0) {
      return { full_credit: true }
    } else if (problems.length === 1) {
      one_report.feedback = "Your solution is nearly perfect, the only problem is that " + problems[0] + "."
    } else if (problems.length === 2) {
      one_report.feedback = "Your solution only has a couple of issues:  " + problems[0] + " and " + problems[1] + "."
    } else {
      one_report.feedback = "Your solution has three issues:  " + problems[0] + ", " + problems[1] + ", and " + problems[2] + "."
    }

    log("final one report", one_report)

    return one_report

  }

  exact_query_match(student_sql, solution_sql_set) {
    // look at all the supplied solutions.  Return true if there is an exact match
    for (const one_solution of solution_sql_set) {
      if (this.collapse_sql_text(one_solution) === this.collapse_sql_text(student_sql)) {
        return true
      }
    }
    return false
  }

  async grade_one_query(score_card) {
    let stu_result
    let key_result
    let stu_columns
    let stu_rows

    // we did not have an exact match in the query text
    log(1)
    stu_result = await this.runQuery(score_card.stu_sql)

    score_card.key_ast = sqlParser.parse(score_card.key_sql);
    if (stu_result.error_message) {
      //student query failed
      //log("Student Query Failed=======================================================================================================")

      //log("stu_result",stu_result )
      score_card.error_message = "Your query did not execute.  You may want to take a second look at it before you submit.  Here's the message from data.world: "
      //log("stu_result.error_message.response",stu_result.error_message.response)
      if (stu_result.error_message.response && stu_result.error_message.response.data) {
        score_card.error_message += stu_result.error_message.response.data
      } else {
        score_card.error_message += JSON.stringify(stu_result.error_message.message)
      }
      score_card.path.push("Student query did not execute")
      //log("Next Action:", "Parse queries")
      score_card.valid_query = false
      score_card.grading_complete = false
    } else {
      // student query executed
      //log("student query executed")
      score_card.path.push("Student query executed")
      score_card.valid_query = true
      stu_columns = this.get_column_names_from_result(stu_result)

      log(2)


      key_result = await this.runQuery(score_card.key_sql)
      if (key_result.error_message) {
        // there was some error at data.world.  We assume all key queries run and run fast, to this has to be a problem at DW
        throw new dwException("There was a problem executing the solution query. This can happen when the database service is experiencing heavy traffic.  Please try again in a few minutes by clicking the back arrow below and starting the submission process again.", key_result.error_message, "key")
      }
      this.key_columns = this.get_column_names_from_result(key_result)
      this.key_rows = this.get_row_data_from_result(key_result, this.key_columns)
      //score_card.correct_row_count = this.key_rows.length === stu_result.data.length-1// -1 because results.data has column headings
      //log("missing 5")

      score_card.columns = {}
      score_card.columns.matching = stu_columns.filter(value => -1 !== this.key_columns.indexOf(value)).length
      score_card.columns.missing = this.key_columns.length - score_card.columns.matching
      score_card.columns.extra = stu_columns.length - score_card.columns.matching

      if (score_card.columns.missing) {
        // student columns do not contain all key columns
        score_card.path.push("student columns does not contain  all key columns")
        score_card.grading_complete = false
      } else {

        // student columns contains key columns
        score_card.path.push("student columns contains all key columns")
        stu_rows = this.get_row_data_from_result(stu_result, this.key_columns)
        this.compare_two_results(stu_rows, this.key_rows, score_card)
      }
    }
  }



  compare_two_results(stu_rows, key_rows, score_card) {
    //compares two single dimensional arrays and evaluates them for sameness
    // returns needed info for score card
    score_card.rows = {}


    if (this.arraysMatch(stu_rows, key_rows)) {
      // student result set matches the key results set
      score_card.path.push("Student records match key records")
      score_card.matching = stu_rows.length
      //score_card.missing=0
      //score_card.extra=0
      score_card.rows.matching = key_rows.length
      score_card.rows.missing = 0
      score_card.rows.extra = 0
      score_card.rows.correct_order = true

      if (score_card.columns.missing === 0 && score_card.columns.extra === 0) {
        score_card.path.push("student columns exact match for key columns")
        score_card.full_credit = true
        score_card.grading_complete = true
      } else {
        score_card.path.push("student columns has extraneous columns")
        score_card.grading_complete = true
      }

    } else {
      // student result set does not match the key results set
      // it may be because it is unsorted.  let's check
      score_card.path.push("Student records do not match key records")
      score_card.rows.matching = stu_rows.filter(value => -1 !== key_rows.indexOf(value)).length
      score_card.rows.missing = key_rows.length - score_card.rows.matching
      score_card.rows.extra = stu_rows.length - score_card.rows.matching
      //score_card.missing_rows=!key_rows.every(val => stu_rows.includes(val))
      //score_card.extra_rows=!stu_rows.every(val => key_rows.includes(val))

      if (score_card.rows.extra === 0) {
        score_card.path.push("Key records contain all student records")

        if (score_card.rows.missing === 0) {
          score_card.path.push("student records contain all key records, so records are correct")
          //score_card.order_status= "mismatch"
          if (score_card.key_ast.value.orderBy) {
            // there is an orderby clause in the key query
            score_card.path.push("there is order by clause in key")
            score_card.full_credit = false
            score_card.grading_complete = false
            score_card.rows.correct_order = false  // debugging 10.2.2020  how can we set false here?  Are we sure?
          } else {
            // there is no order by cluase in the key,  order does not matter
            score_card.path.push("no order by clause in key")
            score_card.full_credit = true
            score_card.grading_complete = true
            score_card.rows.correct_order = true
          }


        } else {
          score_card.path.push("student records do not contain all key records")
          score_card.grading_complete = false
        }
      } else {
        score_card.path.push("Key records do not contain all student records")
        score_card.grading_complete = false
      }

    }
    return score_card
  }



  async parse_queries(score_card, key_columns, key_rows) {
    //   score_card.tables={}
    //   score_card.where={}
    //   score_card.orderby={}

    let key_result

    log("at parse query", key_columns)
    if (key_columns === undefined) {
      log(3)

      key_result = await this.runQuery(score_card.key_sql)
      if (key_result.error_message) {
        // there was some error at data.world.  We assume all key queries run and run fast, to this has to be a problem at DW
        throw new dwException("There was a problem executing the solution query at your database service. This can happen when your service is experiencing heavy traffic.  Please try again in a few minutes.", key_result.error_message, "key")
      }
      key_columns = this.get_column_names_from_result(key_result)
      key_rows = this.get_row_data_from_result(key_result, key_columns)
    }

    //log("parse_queries","1")


    try {
      score_card.stu_ast = sqlParser.parse(score_card.stu_sql);
    } catch (e) {
      //log("in catch of parse stu_sql ast", e)
    }
    //log("parse_queries","2")

    if (score_card.stu_ast) {
      //log("parse_queries","3")

      score_card.path.push("student query parsed")


      if (score_card.columns === undefined) {
        // we have not yet set the columns as missing, extra, matching.  This must be becuase the query could not execute in a propr step.  Let's build columns by looking at the student ast
        let stu_columns = []
        score_card.columns = {}


        for (const item of score_card.stu_ast.value.selectItems.value) {
          if (item.alias) {
            stu_columns.push(item.alias.toLowerCase())
          } else if (item.type === "Identifier") {
            stu_columns.push(item.value.toLowerCase())
          }
        }
        score_card.columns = {}
        score_card.columns.matching = stu_columns.filter(value => -1 !== key_columns.indexOf(value)).length
        score_card.columns.missing = key_columns.length - score_card.columns.matching
        score_card.columns.extra = stu_columns.length - score_card.columns.matching
      }

      if (score_card.rows === undefined) {
        //log("parse_queries","4")

        // query has not yet been executed.  if we made it here, it has parsed. It is most likely becuase
        // the student's select clause was missing columns expected in the key.  we are going to
        // try to plug in the key's select clause and use it to evaluate the rest of the query

        // check to see if student from clause has all the tables that the key from clause has
        const stu_alias_map = this.table_to_alias(score_card.stu_ast.value.from)
        const key_alias_map = this.alias_to_table(score_card.key_ast.value.from)

        //log("stu_alias_map",stu_alias_map)
        //log("key_alias_map",key_alias_map)

        //log("score_card.key_ast.selectItems.value",score_card.key_ast.value.selectItems.value)

        let key_select = JSON.stringify(score_card.key_ast.value.selectItems.value)
        //log("key_select",key_select)

        for (const tbl of Object.keys(key_alias_map)) {
          //log("parse_queries","5")
          let search_clause = '"value":"' + tbl + '.'
          let replace_clause = '"value":"' + stu_alias_map[key_alias_map[tbl]] + '.'
          key_select = key_select.split(search_clause).join(replace_clause)
        }

        //log("key_select2",key_select)
        const modified_stu_ast = JSON.parse(JSON.stringify(score_card.stu_ast))
        modified_stu_ast.value.selectItems.value = JSON.parse(key_select)
        //log("modified_stu_ast",modified_stu_ast)
        //log("query",sqlParser.stringify(modified_stu_ast))
        let new_sql = sqlParser.stringify(modified_stu_ast)
        //log("ABOUT TO PARSE",2)
        if (this.parse_sql_text(score_card)) {
          //log("parse_queries","6")
          // able to chop up the student's sql, let's insert the select clause we just calcualted and run it
          // if not, we'll stick with the new_sql as output by stringify above.

          const temp_card = { stu_sql: new_sql }
          //log("ABOUT TO PARSE",3)

          if (this.parse_sql_text(temp_card)) {
            //log("parse_queries","7")

            //log("temp_card", temp_card)
            new_sql = temp_card.sql_clauses.select
              + score_card.sql_clauses.from
              + score_card.sql_clauses.where
              + score_card.sql_clauses.group
              + score_card.sql_clauses.having
              + score_card.sql_clauses.order
              + score_card.sql_clauses.limit
          }
        }
        // now let's run the newly built query and evaluate it
        //log("=================================================================================")
        let stu_result
        //log("stu_result before",stu_result)
        if (score_card.missing_terms) {
          // the student query is missing important terms, it cannot be correct.  There is no reason to run the query
          //stu_rows=[]
        } else {
          log(4)

          stu_result = await this.runQuery(new_sql)
        }
        //log("stu_result after",stu_result)
        if (!score_card.missing_terms && stu_result.error_message) {
          // there was some error at data.world.  We assume all key queries run and run fast, to this has to be a problem at DW
          //log("parse_queries","8")

          // query parsed but never executed
          // I don't think there is anything to do here

        } else {
          //log("parse_queries","9")
          let stu_rows
          if (score_card.missing_terms) {
            stu_rows = []
          } else {
            stu_rows = this.get_row_data_from_result(stu_result, key_columns)
          }
          this.compare_two_results(stu_rows, key_rows, score_card)

          // this may set grading_complete to true
          //log("just compared the result",score_card)
        }

      } else {
        //log("parse_queries","10")

        // query parsed and was executed in a prior stage, meaning that the columns looked good
        // I don't think there is anything to do here
      }

    }


    if (!score_card.grading_complete && score_card.sql_clauses === undefined) {
      //log("parse_queries","11")
      if (this.parse_sql_text(score_card)) {
        //log("parse_queries","12")
        score_card.path.push("student query text parses")
      } else {
        //log("parse_queries","13")
        score_card.path.push("unable to perform a text parse on student query")
      }
    }

    //log("parse_queries","14")



    // do final scoring


    //log("parse_queries","15")
    score_card.stu_structure = dwqp.parse(score_card.stu_sql)
    //log("parse_queries","16")

    score_card.partial_credit = []
    score_card.partial_credit_message = []
    score_card.no_credit_message = []

    if (score_card.valid_query) { score_card.partial_credit_message.push("Your query is valid SQL") }
    if (!score_card.missing_terms && score_card.columns) {
      if (score_card.columns.missing === 0 && score_card.columns.extra === 0) {
        score_card.partial_credit_message.push("Your query has the right columns")
      } else {
        if (score_card.columns.missing === 1) {
          score_card.no_credit_message.push("Your query is missing an expected column")
        } else if (score_card.columns.missing > 1) {
          score_card.no_credit_message.push("Your query is missing " + score_card.columns.missing + " expected columns")
        }
        if (score_card.columns.extra === 1) {
          score_card.no_credit_message.push("Your query contains a column that is not expected")
        } else if (score_card.columns.extra > 1) {
          score_card.no_credit_message.push("Your query has " + score_card.columns.extra + " columns that are not expected")
        }
      }
    } else {
      score_card.no_credit_message.push("Your query could not be executed")
    }

    if (!score_card.missing_terms && score_card.rows) {
      if (score_card.rows.missing === 0 && score_card.rows.extra === 0) {
        score_card.partial_credit_message.push("Your query prouces the correct result set")
      } else {
        if (score_card.rows.missing === 1) {
          score_card.no_credit_message.push("Your query's result is missing an expected row")
        } else if (score_card.rows.missing > 1) {
          score_card.no_credit_message.push("Your query's result is missing " + score_card.rows.missing + " expected rows")
        }
        if (score_card.rows.extra === 1) {
          score_card.no_credit_message.push("Your query's result contains a row that is not expected")
        } else if (score_card.rows.extra > 1) {
          score_card.no_credit_message.push("Your query's result contains " + score_card.rows.extra + " rows that are not expected")
        }
      }
    }




    if (score_card.stu_structure) {

      // we have an ast-parsed query

      // credit for clauses (ast)
      const clauses = [['selectItems', 'SELECT'], ['from', 'FROM'], ['where', 'WHERE'], ['groupBy', 'GROUP BY'], ['having', 'HAVING'], ['OrderBy', 'ORDER BY'], ['limit', 'LIMIT']]
      for (const clause of clauses) {
        if (score_card.key_ast.value[clause[0]]) {
          //the key has this clause
          if (score_card.stu_ast.value[clause[0]]) {
            // the student query also has the clause
            score_card.partial_credit_message.push("Your query includes the " + clause[1] + " clause")
            score_card.partial_credit.push({
              clause: clause[1],
              status: "exists"
            })
          }
        }
      }


      // scan the key structure and build the partial credit
      for (const clause of Object.keys(score_card.key_structure)) {
        if (score_card.key_structure[clause]) {  // if there is no limit clause, limit will be null
          for (const key of Object.keys(score_card.key_structure[clause])) {
            for (const item of score_card.key_structure[clause][key]) {
              if (score_card.stu_structure[clause] && score_card.stu_structure[clause][key] && score_card.stu_structure[clause][key].includes(item)) {
                log("line 617")
                this.add_once(score_card.partial_credit_message, 'Found "' + item + '" in the ' + clause.toUpperCase() + " clause")
                score_card.partial_credit.push({
                  clause: clause,
                  type: key,
                  item: item,
                  found: score_card.stu_structure[clause][key].includes(item)
                })
              }
            }
          }
        }
      }

    } else if (score_card.sql_clauses.select) {
      // we have a text-prased query

      // credit for clauses (text-parsed)
      const clauses = [['selectItems', 'SELECT', 'select'], ['from', 'FROM', 'from'], ['where', 'WHERE', 'where'], ['groupBy', 'GROUP BY', 'group'], ['having', 'HAVING', 'having'], ['OrderBy', 'ORDER BY', 'order'], ['limit', 'LIMIT', 'limit']]
      for (const clause of clauses) {

        if (score_card.key_ast.value[clause[0]]) {
          //the key has this clause
          if (score_card.sql_clauses[clause[2]]) {
            // the student query also has the clause
            score_card.partial_credit_message.push("Your query includes the " + clause[1] + " clause")
            score_card.partial_credit.push({
              clause: clause[1],
              status: "exists"
            })
          }
        }
      }


      // scan the key structure and build the partial credit
      //log('score_card.key_structure',score_card.key_structure)
      //log('score_card.sql_clauses',score_card.sql_clauses)
      for (const clause of Object.keys(score_card.key_structure)) {
        //log('clause',clause)
        if (score_card.key_structure[clause]) {  // if there is no limit clause, limit will be null
          for (const key of Object.keys(score_card.key_structure[clause])) {
            //log('     key',key)
            for (const item of score_card.key_structure[clause][key]) {
              //log('     item',item)
              if (score_card.sql_clauses[clause].toUpperCase().indexOf(item.toUpperCase()) > -1) {
                this.add_once(score_card.partial_credit_message, 'Found "' + item + '" in the ' + clause.toUpperCase() + " clause")
                score_card.partial_credit.push({
                  clause: clause,
                  type: key,
                  item: item,
                  found: score_card.sql_clauses[clause].toUpperCase().indexOf(item.toUpperCase()) > -1
                })
              }
            }
          }
        }
      }

    } else {
      // can only evaluate based on full text submitted
      // credit for clauses (unparsed)
      let collapsed_sql = this.collapse_sql_text(score_card.stu_sql, true)
      const clauses = [['selectItems', 'SELECT'], ['from', 'FROM'], ['where', 'WHERE'], ['groupBy', 'GROUP BY'], ['having', 'HAVING'], ['OrderBy', 'ORDER BY'], ['limit', 'LIMIT']]
      for (const clause of clauses) {
        if (score_card.key_ast.value[clause[0]]) {
          //the key has this clause
          if (collapsed_sql.indexOf(clause[1]) > -1) {
            // the student query also has the clause
            //log("success with", clause[1], collapsed_sql)
            score_card.partial_credit_message.push("Your query includes the " + clause[1] + " clause")
            score_card.partial_credit.push({
              clause: clause[1],
              status: "exists"
            })
          }
        }
      }



      // credit for key elements found in query
      for (const clause of Object.keys(score_card.key_structure)) {
        if (score_card.key_structure[clause]) {  // if there is no limit clause, limit will be null
          for (const key of Object.keys(score_card.key_structure[clause])) {
            for (const item of score_card.key_structure[clause][key]) {
              if (score_card.stu_sql.toUpperCase().indexOf(item.toUpperCase()) > -1) {
                this.add_once(score_card.partial_credit_message, 'Found "' + item + '" in your solution')
                score_card.partial_credit.push({
                  clause: clause,
                  type: key,
                  item: item,
                  found: score_card.stu_sql.toUpperCase().indexOf(item.toUpperCase()) > -1
                })
              }
            }
          }
        }
      }

    }



    //log("Score Card after parse query----->",score_card)

  }






  // function compare_arrays(key_array, stu_array){  // returns matching, missing, and extra
  //   const result={}
  //   result.matching = stu_array.filter(value => -1 !== key_array.indexOf(value)).length
  //   result.missing = key_array.length - result.matching
  //   result.extra = stu_array.length - result.matching
  //   return result
  // }








  alias_to_table(ast_from) {
    // get a structure that allows us to refer to the aliases used in a from clause by the table name
    // maps tablenames to aliases, so it will only work when each table appears only once in the from clause
    var result = {};
    function recurse(cur, prop) {// copied from flatten

      if (cur) {
        if (cur.alias) {
          if (cur.value.type === "Identifier") {
            result[cur.alias.value] = cur.value.value
          }
        } else if (cur.alias === null) {
          if (cur.value.type === "Identifier") {
            result[cur.value.value] = cur.value.value
          }
        }
      }
      if (Object(cur) !== cur) {
        //result[prop] = cur;

      } else if (Array.isArray(cur)) {
        for (var i = 0, l = cur.length; i < l; i++)
          recurse(cur[i], prop + "[" + i + "]");
        if (l === 0) {
          //result[prop] = [];
        }
      } else {
        var isEmpty = true;
        for (var p in cur) {
          isEmpty = false;
          recurse(cur[p], prop ? prop + "." + p : p);
        }
        if (isEmpty && prop) {
          //result[prop] = {};
        }
      }
    }
    recurse(ast_from.value[0], "");
    return result;
  }

  table_to_alias(ast_from) {
    // get a structure that allows us to refer to the aliases used in a from clause by the table name
    // maps tablenames to aliases, so it will only work when each table appears only once in the from clause
    var result = {};
    function recurse(cur, prop) {// copied from flatten

      if (cur) {
        if (cur.alias) {
          if (cur.value.type === "Identifier") {
            result[cur.value.value] = cur.alias.value
          }
        } else if (cur.alias === null) {
          if (cur.value.type === "Identifier") {
            result[cur.value.value] = cur.value.value
          }
        }
      }
      if (Object(cur) !== cur) {
        //result[prop] = cur;

      } else if (Array.isArray(cur)) {
        for (var i = 0, l = cur.length; i < l; i++)
          recurse(cur[i], prop + "[" + i + "]");
        if (l === 0) {
          //result[prop] = [];
        }
      } else {
        var isEmpty = true;
        for (var p in cur) {
          isEmpty = false;
          recurse(cur[p], prop ? prop + "." + p : p);
        }
        if (isEmpty && prop) {
          //result[prop] = {};
        }
      }
    }
    recurse(ast_from.value[0], "");
    return result;
  }





  parse_sql_text(score_card) {
    //attempt to evaluate the student query by looking for the sql key terms
    //log("parse_sql_text(score_card)",score_card)
    try {
      const sql = this.collapse_sql_text(score_card.stu_sql, true)  // make a copy of the student sql with white space collapsed
      const sql_clear = this.clear_strings_in_query(sql)  // make a copy of the student sql with strings replaced with spaces
      const pos = {}
      pos.select_start = sql_clear.indexOf("SELECT ")
      pos.from_start = sql_clear.indexOf(" FROM ") + 1
      pos.where_start = sql_clear.indexOf(" WHERE ") + 1
      pos.group_start = sql_clear.indexOf(" GROUP BY ") + 1
      pos.having_start = sql_clear.indexOf(" HAVING ") + 1
      pos.order_start = sql_clear.indexOf(" ORDER BY ") + 1
      pos.limit_start = sql_clear.indexOf(" LIMIT ") + 1

      pos.limit_end = sql.length
      if (pos.limit_start === 0) { pos.limit_start = pos.limit_end }

      pos.order_end = pos.limit_start
      if (pos.order_start === 0) { pos.order_start = pos.order_end }

      pos.having_end = pos.order_start
      if (pos.having_start === 0) { pos.having_start = pos.having_end }

      pos.group_end = pos.having_start
      if (pos.group_start === 0) { pos.group_start = pos.group_end }

      pos.where_end = pos.group_start
      if (pos.where_start === 0) { pos.where_start = pos.where_end }

      pos.from_end = pos.where_start
      if (pos.from_start === 0) { pos.from_start = pos.from_end }

      pos.select_end = pos.from_start
      if (pos.select_start === -1) { pos.select_start = pos.select_end }




      score_card.sql_clauses = {}
      score_card.sql_clauses.select = sql.substring(pos.select_start, pos.select_end)
      score_card.sql_clauses.from = sql.substring(pos.from_start, pos.from_end)
      score_card.sql_clauses.where = sql.substring(pos.where_start, pos.where_end)
      score_card.sql_clauses.group = sql.substring(pos.group_start, pos.group_end)
      score_card.sql_clauses.having = sql.substring(pos.having_start, pos.having_end)
      score_card.sql_clauses.order = sql.substring(pos.order_start, pos.order_end)
      score_card.sql_clauses.limit = sql.substring(pos.limit_start, pos.limit_end)

      if (score_card.sql_clauses.select && score_card.sql_clauses.from) {
        return true
      } else {
        return false
      }

    } catch (e) {
      //log("in catch of parse_sql_text", e)
      return false
    }


  }

  /**
   * Runs the given SQL query on the given data.world dataset
   * @param {string} sql SQL statment
   * @param {string} owner the owner of the dataset (not the users account name)
   * @param {string} dataSet the name of the dataset to be queried
   * @param {string} token the users token that allows us to run the query for them. 
   * @returns 
   */
  async runDwQuery(sql, owner, dataSet, token) {
    const url = "https://api.data.world/v0/sql/" + owner + '/' + dataSet + '?query=' + encodeURIComponent(sql) + '&includeTableSchema=true';
    try {
      const request = await fetch(url, {
        method: 'GET',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded', Authorization: 'Bearer ' + token },
      })
      const result = await request.json()
      return { data: result }
    } catch (e) {
      return { error_message: e }
    }
  }

  /**
   * Runs the given SQL query on the given Oracle Autonomus DB. 
   * @param {string} sql SQL statment
   * @param {string} url Authorization URL to run query on Oracle Auto DB
   * @param {string} username Account name
   * @param {string} password Account password
   * @returns 
   */
  async runOracleQuery(sql, url, username, password) {  // sends back the query results as received from data.world or an error message
    const data = new URLSearchParams([
      ['url', url],
      ['sql', sql],
      ['username', username],
      ['password', password],
    ])

    const rawResponse = await fetch('http://localhost:3333/oracle', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      },
      body: data
    })

    return this.formatOracleQueryResponse(await rawResponse.json())
  }

  /**
   * takes the oracle response and converts it into a form that is similar to the data.world respone. 
   * @param {*} data input data that is transformed to match data.world response
   * @returns 
   */
  formatOracleQueryResponse(data) {
    log("data to format",data)
    try {
      const queryResult = data.items[data.items.length - 1]
      if (queryResult.errorCode) {
        return {
          error_message: {
            response: {
              data: queryResult.errorMessage,
              errorCode: queryResult.errorCode,
              errorColumn: queryResult.errorColumn,
              errorLine: queryResult.errorLine,
            }
          }
        }
      }

//log("}}}}}}}}}}queryResult}}",queryResult)

      return {
        data: [{
          fields: queryResult.resultSet.metadata.map(x => ({
            name: x.columnName,
            type: x.columnTypeName,
          }))
        }, ...queryResult.resultSet.items],
        status: 200,
        statusText: "",
      }
    } catch (error) {
      console.error(error)
      if (data.message) {
        throw new ShowableError(data.message)
      }
      return {
        error_message: {
          response: {
            data: "unable to parse query results"
          }
        }
      }
    }
  }


  collapse_sql_text(data, use_space) {  //uppercases everyting unless it is inside of quotes (single or double) and collapses all sequential whitespace into a single space
    const result = data.split("")
    let quotechar = ""
    for (let x = 0; x < result.length; x++) {
      switch (result[x]) {
        case "'":
          if (quotechar === "'") {
            quotechar = ""
          } else if (quotechar === "") {
            quotechar = "'"
          }
          break
        case '"':
          if (quotechar === '"') {
            quotechar = ""
          } else if (quotechar === "") {
            quotechar = '"'
          }
          break
        default:
      }
      if (quotechar === "") {
        result[x] = result[x].toUpperCase().replace(/\s/g, String.fromCharCode(7))
      }
    }

    const space_exp = "(\x07)+"  // compiler is complaining if I put the "\" directly in the regex below, so had to put it in variable--lame
    if (use_space) {
      return result.join("").replace(RegExp(space_exp, 'g'), " ").trim()
    } else {
      return result.join("").replace(RegExp(space_exp, 'g'), "").trim()
    }
  }

  get_column_names_from_ast(ast) {  //returns array of field names from an abstract syntax tree
    let data = []
    for (const col of ast.value.selectItems.value) {
      data.push(col.value.toLowerCase())
    }
    return data
  }

  get_column_names_from_result(result) {  //returns array of field names from dw query response
    let data = []
    for (const col of result.data[0].fields) {
      data.push(col.name.toLowerCase())
    }
    return data
  }
  fixnull(data) {
    if (data === null) {
      return ""
    }
    return data
  }
  get_row_data_from_result(result, columns) {  //returns an array with column values concatenated for each row in the result
    //log("At get_row_data_from_result",result, columns)
    let data = []
    for (let r = 1; r < result.data.length; r++) {
      let row_data = ""
      let row = this.objectKeysToLowerCase(result.data[r])
      for (const col of columns) {
        row_data += "~" + this.fixnull(row[col])
      }
      data.push(row_data)
    }
    return data
  }

  // make all keys of an object lowercase
  objectKeysToLowerCase(origObj) {
    return Object.keys(origObj).reduce( (newObj, key) => {
      let val = origObj[key];
      let newVal = (typeof val === 'object') ? this.objectKeysToLowerCase(this.fixnull(val)) : this.fixnull(val);
      newObj[key.toLowerCase()] = newVal;
      return newObj;
    }, {});
  }

  arraysMatch(arr1, arr2) {

    // Check if the arrays are the same length
    if (arr1.length !== arr2.length) return false;

    // Check if all items exist and are in the same order
    for (var i = 0; i < arr1.length; i++) {
      //log("arrays match", arr1[i], arr2[i])
      if (arr1[i] !== arr2[i]) {
        return false
      };
    }
    return true

  };


  clear_strings_in_query(data) {
    // replaces all strings in query with spaces.  Used to make sure we don't find key words in strings when we are parsing a query
    // when data =           "select * from customer where lastname='''O''Ma''''lley''' and fisrtname='Shamus'"
    // this function returns "select * from customer where lastname='                 ' and fisrtname='      '"
    const sql_array = data.split("")
    const string_array = new Array(sql_array.length)
    let string_char = ""
    let just_started = false
    let quote_in_quote = false
    for (let x = 0; x < data.length; x++) {
      if ((sql_array[x] === "'" || sql_array[x] === '"' || sql_array[x] === '`')) {
        switch (string_char) {
          case "'":
            // we are in a single-quote terminated string check to see if we are ending it
            if (x === sql_array.length - 1) {
              // it's the last character of the array, we must be ending
              string_char = ""
            } else if (sql_array[x + 1] === "'") {
              // we have quote in quote
              quote_in_quote = !quote_in_quote
            } else {
              if (quote_in_quote) {
                quote_in_quote = false
              } else {
                string_char = ""
              }
            }
            break
          case '"':
            // we are in a double-quote terminated string check to see if we are ending it
            if (x === sql_array.length - 1) {
              // it's the last character of the array, we must be ending
              string_char = ""
            } else if (sql_array[x + 1] === '"') {
              // we have quote in quote
              quote_in_quote = !quote_in_quote
            } else {
              if (quote_in_quote) {
                quote_in_quote = false
              } else {
                string_char = ""
              }
            }
            break
          case '`':
            // we are in a back-tick terminated string check to see if we are ending it
            if (x === sql_array.length - 1) {
              // it's the last character of the array, we must be ending
              string_char = ""
            } else if (sql_array[x + 1] === '`') {
              // we have quote in quote
              quote_in_quote = !quote_in_quote
            } else {
              if (quote_in_quote) {
                quote_in_quote = false
              } else {
                string_char = ""
              }
            }
            break
          default:
            //we are just staring a string, set the character that identifies it
            string_char = sql_array[x]
            just_started = true
        }
      }
      if (string_char === "" || just_started) {
        string_array[x] = " "
      } else {
        string_array[x] = sql_array[x]
        sql_array[x] = " "
      }

      //log(sql_array[x],string_array[x])
      just_started = false
    }
    return sql_array.join("")

  }

  add_once(array, value) { //add the value to the array if it is not already there
    if (array.indexOf(value) === -1) {
      array.push(value)
    }
  }



  /**
   * Runs the given query, returns the data result for grading
   * 
   * It uses local storage to get the dbType which could be
   * - 'oracle'
   * - 'data.world'
   * @param {string} sql the sql statement to be run that returns data for grading
   * @returns 
   */
  async runQuery(sql) {
    this.dispatch("Running query")
    const resp = this.formatOracleQueryResponse(
      await run_db_query({
        ...this.bookQueryParams,
        query: sql
      })
    )
    this.dispatch("Query complete")
    return resp
  }

}
