# Copyright 2017 Battelle Energy Alliance, LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
  This Module performs Unit Tests for the xmlUtils methods
  It cannot be considered part of the active code but of the regression test system
"""

#For future compatibility with Python 3
from __future__ import division, print_function, unicode_literals, absolute_import
import warnings
warnings.simplefilter('default',DeprecationWarning)

import os,sys
import numpy as np
import xml.etree.ElementTree as ET

frameworkDir = os.path.normpath(os.path.join(os.path.dirname(__file__),os.pardir,os.pardir,os.pardir,os.pardir,'framework'))
sys.path.append(frameworkDir)
from utils import xmlUtils, utils


print (xmlUtils)

results = {"pass":0,"fail":0}
#type comparison
elemType = type(ET.Element('dummy'))
treeType = type(ET.ElementTree())
#cleanup utilities
toRemove = []

def checkAnswer(comment,value,expected,tol=1e-10,updateResults=True):
  """
    This method is aimed to compare two floats given a certain tolerance
    @ In, comment, string, a comment printed out if it fails
    @ In, value, float, the value to compare
    @ In, expected, float, the expected value
    @ In, tol, float, optional, the tolerance
    @ In, updateResults, bool, optional, if True updates global results
    @ Out, None
  """
  if abs(value - expected) > tol:
    print("checking answer",comment,value,"!=",expected)
    if updateResults:
      results["fail"] += 1
    return False
  else:
    if updateResults:
      results["pass"] += 1
    return True

def checkArray(comment,check,expected,tol=1e-10):
  """
    This method is aimed to compare two arrays of floats given a certain tolerance
    @ In, comment, string, a comment printed out if it fails
    @ In, check, list, the value to compare
    @ In, expected, list, the expected value
    @ In, tol, float, optional, the tolerance
    @ Out, None
  """
  same=True
  if len(check) != len(expected):
    same=False
  else:
    for i in range(len(check)):
      same = same*checkAnswer(comment+'[%i]'%i,check[i],expected[i],tol,False)
  if not same:
    print("checking array",comment,"did not match!")
    results['fail']+=1
    return False
  else:
    results['pass']+=1
    return True

def checkType(comment,value,expected,updateResults=True):
  """
    This method compares the data type of two values
    @ In, comment, string, a comment printed out if it fails
    @ In, value, float, the value to compare
    @ In, expected, float, the expected value
    @ In, updateResults, bool, optional, if True updates global results
    @ Out, None
  """
  if type(value) != type(expected):
    print("checking type",comment,value,'|',type(value),"!=",expected,'|',type(expected))
    if updateResults:
      results["fail"] += 1
    return False
  else:
    if updateResults:
      results["pass"] += 1
    return True

def attemptFileClear(fName,later):
  """
    Attempts to remove the file.  If not possible, store it in "later".
    @ In, fName, string, name of file to remove
    @ In, later, list, list of files to remove later
    @ Out, later, list, list of files to remove later
  """
  try:
    os.remove(fName)
  except OSError:
    later.append(fName)
  return later

#establish test XML
xmlString = '<root ratr="root_attrib"><child catr1="child attrib 1" catr2="child attrib 2"><cchild ccatr="cc_attrib">cchildtext</cchild></child></root>'
inFileName = 'testXMLInput.xml'
open(inFileName,'w').write(xmlString)
xmlTree = ET.parse(inFileName)
toRemove = attemptFileClear(inFileName,toRemove)

# test prettify
pretty = utils.toString(xmlUtils.prettify(xmlTree))
prettyFileName = 'xml/testXMLPretty.xml'
open(prettyFileName,'w').writelines(pretty)
gold = ''.join(line.rstrip('\n\r') for line in open(os.path.join(os.path.dirname(__file__),'gold',prettyFileName),'r'))
test = ''.join(line.rstrip('\n\r') for line in open(                    prettyFileName ,'r'))
if gold==test:
  results['pass']+=1
  toRemove = attemptFileClear(prettyFileName,toRemove)
else:
  print('ERROR: Test of "pretty" failed!  See',prettyFileName,'(below) vs gold/',prettyFileName)
  print('( START',prettyFileName,')')
  for line in file(prettyFileName,'r'):
    print(line[:-1]) #omit newline
  print('( END',prettyFileName,')')
  results['fail']+=1

# test newNode
### test with tag, text, and multiple attributes
node = xmlUtils.newNode('tagname',text="text",attrib={'atr1':'atr1_text','atr2':'atr2_text'})
okay = True
#type
if type(node)!=elemType:
  okay = False
  print('Test of "newNode" failed!  Returned node was not an xml.etree.ElementTree!  Instead was:',type(node))
#tag
if node.tag!='tagname':
  okay = False
  print('ERROR: Test of "newNode" failed!  Tag should have been "tagname" but instead was "'+node.tag+'".')
#text
if node.text!='text':
  okay = False
  print('ERROR: Test of "newNode" failed!  Text should have been "text" but instead was "'+node.text+'".')
#attributes
if 'atr1' not in node.attrib.keys():
  okay = False
  print('ERROR: Test of "newNode" failed!  Did not find attribute "atr1" in keys:',node.attrib.keys())
else:
  if node.attrib['atr1']!='atr1_text':
    okay = False
    print('ERROR: Test of "newNode" failed! Attribute "atr1" should have been "atr1_text" but was',node.attrib['atr1'])
if 'atr2' not in node.attrib.keys():
  okay = False
  print('ERROR: Test of "newNode" failed!  Did not find attribute "atr2" in keys:',node.attrib.keys())
else:
  if node.attrib['atr2']!='atr2_text':
    okay = False
    print('ERROR: Test of "newNode" failed! Attribute "atr2" should have been "atr2_text" but was',node.attrib['atr2'])
if okay:
  results['pass']+=1
else:
  results['fail']+=1

# test newTree
tree = xmlUtils.newTree('newroot')
okay = True
if type(tree) != treeType:
  okay = False
  print('ERROR: Test of "newTree" failed!  Returned tree was not xml.etree.ElementTree.ElementTree, instead was',type(tree))
elif tree.getroot().tag != 'newroot':
  okay = False
  print('ERROR: Test of "newTree" failed!  Root of new tree should be "newroot" but instead got',tree.getroot().tag)
if okay:
  results['pass']+=1
else:
  results['fail']+=1