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) {

    console.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() === '') {
      console.log("=-----> Query Graded: No Query Found")
      return { zero_credit: true, complexity_index: -1 }
    } else if (this.exact_query_match(student_sql, solution_sql_set)) {
      console.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
      console.log("=-----> Query Graded: Exact Match")
      return { full_credit: true, complexity_index: -1, exact_match: true }
    } else {
      console.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
      //console.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
      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

      let presentation_count = 0
      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)

      console.log("score", score_card)

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

    console.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
    console.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
      //console.log("Student Query Failed=======================================================================================================")

      //console.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: "
      //console.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")
      //console.log("Next Action:", "Parse queries")
      score_card.valid_query = false
      score_card.grading_complete = false
    } else {
      // student query executed
      //console.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)

      console.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
      //console.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

    console.log("at parse query", key_columns)
    if (key_columns === undefined) {
      console.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)
    }

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


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

    if (score_card.stu_ast) {
      //console.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) {
        //console.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)

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

        //console.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)
        //console.log("key_select",key_select)

        for (const tbl of Object.keys(key_alias_map)) {
          //console.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)
        }

        //console.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)
        //console.log("modified_stu_ast",modified_stu_ast)
        //console.log("query",sqlParser.stringify(modified_stu_ast))
        let new_sql = sqlParser.stringify(modified_stu_ast)
        //console.log("ABOUT TO PARSE",2)
        if (this.parse_sql_text(score_card)) {
          //console.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 }
          //console.log("ABOUT TO PARSE",3)

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

            //console.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
        //console.log("=================================================================================")
        let stu_result
        //console.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 {
          console.log(4)

          stu_result = await this.runQuery(new_sql)
        }
        //console.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
          //console.log("parse_queries","8")

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

        } else {
          //console.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
          //console.log("just compared the result",score_card)
        }

      } else {
        //console.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) {
      //console.log("parse_queries","11")
      if (this.parse_sql_text(score_card)) {
        //console.log("parse_queries","12")
        score_card.path.push("student query text parses")
      } else {
        //console.log("parse_queries","13")
        score_card.path.push("unable to perform a text parse on student query")
      }
    }

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



    // do final scoring


    //console.log("parse_queries","15")
    score_card.stu_structure = dwqp.parse(score_card.stu_sql)
    //console.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)) {
                console.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
      //console.log('score_card.key_structure',score_card.key_structure)
      //console.log('score_card.sql_clauses',score_card.sql_clauses)
      for (const clause of Object.keys(score_card.key_structure)) {
        //console.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])) {
            //console.log('     key',key)
            for (const item of score_card.key_structure[clause][key]) {
              //console.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
            //console.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
                })
              }
            }
          }
        }
      }

    }



    //console.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
    //console.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) {
      //console.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) {
    console.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,
            }
          }
        }
      }
      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
    //console.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++) {
      //console.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] = " "
      }

      //console.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
  }

}
