#!/usr/bin/python
# -*- coding: utf-8 -*-

def run_case (case_id,check_dco,check_hpa):
	case5 = '''
	<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<h2><a name="%s_procedures">Run Procedures for Test Case %s</a></h2>
<li>Select variation.
<li>Select a drive that does not support the secure erase command and that uses the <IFACE> interface required by the variation. 
<li>No initialization required for test drive.
<li>If the tool under test requires a host computer to execute the test, then select and configure a test host as needed to support the tool.
<li>Manually calibrate the system clock on test host if applicable. 
<li>Select an analysis host.
<li>Manually calibrate the system clock on the analysis host. 
<li>Execute the following command:
<p><tt>logfmp <VAR> analysis-host operator drive test-host</tt>
<li>Prepare to run the tool under test:
<li>Configure tool under test and attach the test drive.
<li>Select erase mode if applicable. 
<li>If the tool under test creates a log file and offers a choice for log file name use tool-log.txt for the name.
<li>Run tool under test.
<li>Record any message displayed by the tool under test. Use a filename of message.txt. 
<li>Any tool parameter settings that are used need to be recorded in the testrun-note.txt file 
'''
	html = '''
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<h2><a name="%s_procedures">Run Procedures for Test Case %s</a></h2>
<li>Select a drive that <SE> the secure erase command and that uses the <IFACE> interface required by the variation. 
<li>If the tool under test requires a host computer to execute the test, then select and configure a test host as needed to support the tool.
<li>Manually calibrate the system clock on test host if applicable. 
<li>Select an analysis host.
<li>Manually calibrate the system clock on the analysis host. 
<li>Execute the following command: 
<p><tt>logfmp <VAR> analysis-host operator drive test-host</tt>
<li>Do an analysis of the initial state with dsumm.
<p><tt>dd bs=512 if=/dev/xxx | dsumm <VAR> analysis_host operator /dev/xxx label init.txt </tt>
<li>Prepare to run the tool under test:
<li>Configure tool under test and attach the test drive.
<li>Select write mode if applicable. 
<li>If the tool under test creates a log file and offers a choice for log file name use tool-log.txt for the name.
<li>Run tool under test.
<li>Any tool parameter settings that are used need to be recorded in the testrun-note.txt file 
<POSTRUN>
<li>Count the number of times each byte value is present with dsumm.
<p><tt>dd bs=512 if=/dev/xxx | dsumm <VAR>  analysis_host operator /dev/xxx label analysis.txt</tt>
<li>Identify overwritten and unchanged sectors with ransum.
<p><tt>dd bs=512 if=/dev/xxx | ransum <VAR>  analysis_host operator /dev/xxx label runs.txt</tt>
'''
	case_parms = case_id.split('-')
	print '<h1><a name = %s>TEST CASE %s variation %s</h1>' % (case_id,case_parms[1],case_parms[2])
#	print '<h2><a name="%s_eval">Evaluating %s</a></h2>' % (testcase,testcase)
	if case_parms[1] == '05': html = case5
	else:
		postrun = run_hdat() + '<li>record size of drive as size_postwipe'
		if case_id.find('DCO') != -1:
			postrun = postrun + remove_dco()
		if case_id.find('HPA') != -1:
			postrun = postrun + remove_hpa()
		html = html.replace('<POSTRUN>',postrun)
	html = html.replace('<VAR>',case_id)
	if case_parms[1] == '02' or case_parms[1] == '04':
		html = html.replace ('<SE>','supports')
	else:
		html = html.replace ('<SE>','does not support')
	if (case_id.find('DCO') != -1) or (case_id.find('HPA') != -1):
		html = html.replace ('<IFACE>','(S)ATA')
	else:
		html = html.replace ('<IFACE>',case_parms[2])
#def drive_init(is_ata,need_dco,need_hpa):
	need_dco = case_id.find('DCO') != -1
	need_hpa = case_id.find('HPA') != -1
	if case_id.find ('ATA') != -1 or need_dco or need_hpa: is_ata = 1
	else: is_ata = 0
	if case_parms[1] != '05':
		setup_drive_proc = drive_init(is_ata,need_dco,need_hpa)
		setup_drive_proc = setup_drive_proc.replace('<VAR>',case_id)
		print setup_drive_proc
	return html % (case_id,case_id)
# ====================================================
def run_hdat():
	html = '''
<h4> Run HDAT2 </h4>
<li>Boot system with the hdat2 boot floppy.
<li>Press 1 to bypass the decrementing startup file menu time. If 1 is not pressed, after a few seconds, the startup file menu becomes the command screen.
<li>At the command screen, type HDAT2 and then press Enter.
<li>At the Device List screen, select the destination drive using the up or down arrow keys to highlight the drive. Press Enter.
'''
	return html

def create_dco():
	html = '''
<h4> Create DCO </h4>
<li>At the Main Menu, select Device Configuration Overlay Menu. Press Enter.
<li>At the Device Configuration Overlay Menu, select Modify. Press Enter.
<li>At the DCO Menu, select the number of sectors to the right of Maximum LBA sectors. Press Insert.
<li>Type the desired amount of sectors. Press Enter.
<li>If the configuration is not what is you intended, repeat step 3 until the desired configuration is achieved.
<li>If the capacity is what you intended, press S and then Y to confirm the settings.
<li>Press Esc n times to exit the program.
<li>At the command screen, type HDAT2.
<li>At the Device List verify the drive capacity is as intended.
<li>Save the identify device output to the default save file, HDATCOPY.TXT, then rename the HDATCOPY.TXT file to hdat-dco.txt.
'''
	return html


def remove_dco():
	html = '''
<h4> Remove DCO </h4>
<li>At the Main Menu, using the arrow keys, select Device Configuration Overlay Menu. Press Enter.
<li>At the Device Configuration Overlay Menu, using the arrow keys highlight Restore. Press Enter. Press Y when prompted "Are you sure you want to RESTORE Device Configuration?"
<li>Press the Esc key n times to exit the program.
<li>At the command screen, type HDAT2.
<li>At the Device List screen verify the drive capacity is as intended.
'''
	return html


def create_hpa():
	html = '''
<h4> Create HPA </h4>
<li>At the Main Menu, select SET MAX (HPA) Menu. Press Enter.
<li>At the SET MAX (HPA) Menu, select Set Max Address. Press Enter.
<li>At the SET MAX ADDRESS screen, press the Insert key on the keyboard.
<li>Type the desired amount of sectors to the right of the New Value field. Press Enter. 
<li>If the configuration is not what is you intended, repeat step 4 until the desired configuration is achieved.
<li>If the configuration is what you intended, press S, then Y, to confirm the operation. Once Y is pressed the user is instructed to press any key. After pressing a key, the screen refreshes and the user may see the updated size.
<li>Save the identify device output to the default save file, HDATCOPY.TXT, then rename the HDATCOPY.TXT file to hdat-hpa.txt.
'''
	return html


def remove_hpa():
	html = '''
<h4> Remove HPA </h4>
<li>At the Main Menu, select SET MAX (HPA) Menu. Press Enter.
<li>At the SET MAX (HPA) Menu, select Set Max Address. Press Enter.
<li>At the SET MAX ADDRESS screen, select the New Value field option. 
<li>Press the Insert key on your keyboard to place New Value into edit mode.
<li>Type in the desired amount of sectors required. Press S to validate. 
<li>If the configuration is not what is you intended, repeat step 3a until the desired configuration is achieved.
<li>If the capacity is what you intended, then press S and then Y to confirm. Once Y is pressed the user is instructed to press any key to continue. After pressing a key, the screen refreshes and the user may see the updated size.
'''
	return html

def drive_init(is_ata,need_dco,need_hpa):
	html = '''
<h3> Setup Drive </h3>
<li>Select removable media for saving of log files.
<li>If not already initialized, initialize removable media for saving log files.
<li>Create a directory on the removable media for the current test case.
<li>Select a destination drive according to test case criteria.
%s
<h3> Write initial content </h3>
<li>Select a host computer to initialize the destination drive contents.
<li>Manually calibrate the system clock on the selected host. 
<li>Run FS-TST diskwipe to initialize the destination drive contents.
<p><tt>diskwipe <VAR> host operator /dev/xxx label -src -new_log </tt>
<li>Do an analysis of the initial state with dsumm.
<p><tt>dd bs=512 if=/dev/xxx | dsumm <VAR> analysis_host operator /dev/xxx label init.txt </tt>
%s
<li>Any comments about drive setup that need to be included in the test report can be included in a file named setup-note.txt.
<li>Save the log files from diskwipe, dsumm, and setup-note.txt in the test case directory.
<h3> Setup Complete </h3>
'''
	if (need_dco or need_hpa):
		hidden = run_hdat()
	else: hidden = ''
	if is_ata:
		remove_hidden = '''
<li>Check for the presence of HPA or DCO. (NOTE: If both an HPA and a DCO are present, the HPA must be removed first).
<li>Remove the HPA if present. 
%s
<li>Check for the presence of a DCO.
<li>Remove DCO if present.
%s
'''
		remove_hidden = remove_hidden % (run_hdat()+remove_hpa(),remove_dco()+'<h4>Hidden area removed</h4>')
	else: remove_hidden = ''
	if need_dco: hidden = hidden + create_dco() + '<li>Record size as size_with_dco'
	if need_hpa: hidden = hidden + create_hpa() + '<li>Record size as size_with_hpa'
	if need_dco or need_hpa: hidden = hidden + '<h4>Hidden area complete</h4>'
	return html % (remove_hidden + '<li>Record drive size as size_no_hidden',hidden)

html="""
<html><body>
<TITLE>If you see this, SNAP!</TITLE>
<H1>Test Plan</H1>
<HR>
<P>stuff</P>
<HR>"""
tail = '''
</body></html>
'''


r_list = [
'''
<h3>Wipe sectors via WRITE command</h3> <p>Output of <b>ransum</b> should
indicate that at least sectors 0 through <END> sectors overwritten
''',
'''
<h3>Wipe sectors via ERASE command</h3> <p>Output of <b>ransum</b> should
indicate that at least sectors 0 through <END> sectors overwritten
''',
"<h3>Wipe hidden DCO sectors</h3><p>Output of <b>ransum</b> should indicate DCO wiped",
"<h3>Wipe hidden HPA sectors</h3><p>Output of <b>ransum</b> should indicate HPA wiped",
"<h3>Remove DCO</h3><p>The size_postwipe should match size_no_hidden",
"<h3>Remove HPA</h3><p>The size_postwipe should match size_no_hidden",
"<h3>Detect attempt to use ERASE on unsupporting drive</h3><p>Tool gives indication that it cannot proceed"
]

r_by_case = {
'01' : 0,
'02' : 1,
'03' : 0,
'04' : 1,
'05' : 6
}

spacer='''
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
'''
def print_version():
	print "<p>@(#) sap_fmp.py Version 1.2 UPDATED 03/23/10 15:13:16"

def wrap_case (testcase,check_dco,check_hpa):
	print spacer
	print '<HR>'
	print '<ol>'
	setup = run_case(testcase,check_dco,check_hpa)
	print setup 
	print '</ol>'
	print spacer
	print '<h2><a name="%s_eval">Evaluating %s</a></h2>' % (testcase,testcase)
#	print '<a href="#%s_procedures"> %s</a>' % (testcase,'Test Run Procedures')
#	print '<a href="#%s_eval"> %s</a>' % (testcase,'Test Evaluation')

	this_case_r_list = []
	var = testcase.split('-')
	this_case_r_list.append (r_by_case[var[1]])
	last_sector = 'size_no_hidden'
	if testcase.find('DCO') != -1:
		this_case_r_list.append (2)
		if check_dco: this_case_r_list.append (4)
		last_sector = 'size_with_dco'
	if testcase.find('HPA') != -1:
		this_case_r_list.append (3)
		if check_hpa: this_case_r_list.append (5)
		last_sector = 'size_with_hpa'
	for req in this_case_r_list:
		print r_list[req].replace('<END>',last_sector)

report_header_text = '''
<p>Tool Name: [INSERT]
<br>Tool Version: [INSERT]
<br>Vendor: [INSERT]
<br><br>
<br>Agency conducting test: [INSERT]
<br>Contact: [INSERT]
<br>Report date:  [INSERT]
<br>Authored by:  [INSERT]
<br>Reviewed by/date:  [INSERT]
<br>Approved by/date : [INSERT]
<br>
<h2>Tool Description</h2>
 [INSERT]
<h2>Results Summary</h2>
<h3>Observations:</h3>
 [INSERT]
<h3>Concerns:</h3>
 [INSERT]
<h3>Tool Limitations:</h3>
 [INSERT]
<h3>Recommendations:</h3>
 [INSERT]
<h2>Test Environment</h2>
<br>Hardware:  [INSERT]
<br>OS: [INSERT]
<br>Software: [INSERT]
<h2>Test Results by Case</h2>
'''

results_by_case = {
'01' : '''
<br>Total number of sectors  [INSERT]
<br>Number of sectors wiped  [INSERT]
''',
'02' : '''
<br>Total number of sectors  [INSERT]
<br>Number of sectors wiped  [INSERT]
''',
'03' : '''
<br>Total number of visible sectors  [INSERT]
<br>Total number of hidden sectors  [INSERT]
<br>Total number of sectors  [INSERT]
<br>Number of visible sectors wiped  [INSERT]
<br>Number of hidden sectors wiped  [INSERT]
<br>Number of sectors wiped  [INSERT]
<br>State of hidden area (removed or not)  [INSERT]
''',
'04' : '''
<br>Total number of visible sectors  [INSERT]
<br>Total number of hidden sectors  [INSERT]
<br>Total number of sectors  [INSERT]
<br>Number of visible sectors wiped  [INSERT]
<br>Number of hidden sectors wiped  [INSERT]
<br>Number of sectors wiped  [INSERT]
<br>State of hidden area (removed or not)  [INSERT]
''',
'05' : 'Message indicating ERASE not supported (yes or no) [INSERT]'
}


def report_header ():
	print '<h1><a name = test_report>Test Report for [INSERT: TOOL NAME/VERSION]</h1>'
	print report_header_text

def case_report (testcase,check_dco,check_hpa):
	print '<h3>Test case %s</h3>' % testcase
	var = testcase.split('-')
	print results_by_case[var[1]]

#print html
#case_list = [ 'FMP-01-ATA28', 'FMP-01-USB', 'FMP-05-SATA', 'FMP-02-SATA48', 'FMP-03-DCO','FMP-03-DCO+HPA']
#print '<ul>'
#for testcase in case_list:
#	print '<li>'
#	print '<a href="#%s">%s</a>' % (testcase,testcase)
#print '</ul>'
#print '<HR>'
#for testcase in case_list:
#	wrap_case(testcase)
#print tail
