/*
 * Copyright 2015 Google Inc. All rights reserved.
 *
 * 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.
 */

package cherry

import (
	"strings"
	"time"
	"bytes"
	"log"
	"strconv"
	"io"
)

type BatchSessionInfo struct {
	ADBSerialNumber			string		`json:"adbSerialNumber"` // Empty for non-adb devices.

	ReleaseName				string		`json:"releaseName"`
	ReleaseId				string		`json:"releaseId"`
	BuildTargetName			string		`json:"buildTargetName"`
	ResultName				string		`json:"resultName"`
	Timestamp				time.Time	`json:"timestamp"`

	TargetAddress			string		`json:"targetAddress"`
	TargetPort				int			`json:"targetPort"`
	SpawnLocalProcess		string		`json:"spawnLocalProcess"`
	DeviceId				string		`json:"deviceId"`
	TestBinaryName			string		`json:"testBinaryName"`
	TestBinaryCommandLine	string		`json:"testBinaryCommandLine"`
	TestBinaryWorkingDir	string		`json:"testBinaryWorkingDir"`

	CandyTargetName			string		`json:"candyTargetName"`
	CandyConfigName			string		`json:"candyConfigName"`
}

type LogContainerParser struct {
	sessionInfo			BatchSessionInfo
	isInsideSession		bool
	currentCasePath		string
	currentCaseLog		bytes.Buffer

	resultQueue			chan<- TestExecutorEvent
}

type LogContainerWriter struct {
	dst					io.Writer
	err					error
	isSessionStarted	bool
	isFinished			bool
}

func CreateLogContainerParser (resultQueue chan<- TestExecutorEvent) *LogContainerParser {
	return &LogContainerParser {
		resultQueue: resultQueue,
	}
}

func split2 (s string, delim string) (string, string) {
	strs := strings.SplitN(s, delim, 2)
	last := ""
	if len(strs) == 2 { last = strs[1] }
	return strs[0], last
}

func parseTimestamp (timestamp string) time.Time {
	// \todo [nuutti] Timezones
	if t, err := time.Parse("2006-01-02 15:04:05Z", timestamp); err == nil { return t }
	if t, err := time.Parse("1/2/2006 3:04:05 PM", timestamp); err == nil { return t }
	if t, err := time.Parse("02/01/2006 15:04:05", timestamp); err == nil { return t }
	if t, err := time.Parse("2.1.2006 15:04:05", timestamp); err == nil { return t }
	return time.Time{}
}

func parseTestStatusCode (statusString string) TestStatusCode {
	switch "TSC" + statusString {
		case string(TEST_STATUS_CODE_PASS):						return TEST_STATUS_CODE_PASS
		case string(TEST_STATUS_CODE_FAIL):						return TEST_STATUS_CODE_FAIL
		case string(TEST_STATUS_CODE_QUALITY_WARNING):			return TEST_STATUS_CODE_QUALITY_WARNING
		case string(TEST_STATUS_CODE_COMPATIBILITY_WARNING):	return TEST_STATUS_CODE_COMPATIBILITY_WARNING
		case string(TEST_STATUS_CODE_PENDING):					return TEST_STATUS_CODE_PENDING
		case string(TEST_STATUS_CODE_RUNNING):					return TEST_STATUS_CODE_RUNNING
		case string(TEST_STATUS_CODE_NOT_SUPPORTED):			return TEST_STATUS_CODE_NOT_SUPPORTED
		case string(TEST_STATUS_CODE_RESOURCE_ERROR):			return TEST_STATUS_CODE_RESOURCE_ERROR
		case string(TEST_STATUS_CODE_INTERNAL_ERROR):			return TEST_STATUS_CODE_INTERNAL_ERROR
		case string(TEST_STATUS_CODE_CANCELED):					return TEST_STATUS_CODE_CANCELED
		case string(TEST_STATUS_CODE_TIMEOUT):					return TEST_STATUS_CODE_TIMEOUT
		case string(TEST_STATUS_CODE_CRASH):					return TEST_STATUS_CODE_CRASH
		case string(TEST_STATUS_CODE_DISABLED):					return TEST_STATUS_CODE_DISABLED
		default:												return TestStatusCode("")
	}
}

func parseIntOrDefault (s string, def int) int {
	i, err := strconv.Atoi(s)
	if err != nil { return def }
	return i
}

func (parser *LogContainerParser) parseSessionInfo (line string) {
	key, value := split2(line, " ")
	if value == "" {
		log.Println("[qpa] warning: empty value in #sessionInfo")
	} else if value[0] == '"' {
		last := strings.LastIndex(value, `"`)
		if last == 0 {
			log.Println("[qpa] warning: missing double quote in #sessionInfo line")
		} else {
			value = value[1 : last]
		}
	}

	switch key {
		case "adbSerialNumber":					parser.sessionInfo.ADBSerialNumber			= value
		case "candyTargetName":					parser.sessionInfo.CandyTargetName			= value
		case "resultName":						parser.sessionInfo.ResultName				= value
		case "targetName":						parser.sessionInfo.BuildTargetName			= value
		case "releaseName":						parser.sessionInfo.ReleaseName				= value
		case "releaseId":						parser.sessionInfo.ReleaseId				= value
		case "configName":						parser.sessionInfo.CandyConfigName			= value
		case "timestamp":						parser.sessionInfo.Timestamp				= parseTimestamp(value)
		case "cherryTargetAddress":				parser.sessionInfo.TargetAddress			= value
		case "cherryTargetPort":				parser.sessionInfo.TargetPort				= parseIntOrDefault(value, 0)
		case "cherrySpawnLocalProcess":			parser.sessionInfo.SpawnLocalProcess		= value
		case "cherryDeviceId":					parser.sessionInfo.DeviceId					= value
		case "cherryTestBinaryName":			parser.sessionInfo.TestBinaryName			= value
		case "cherryTestBinaryCommandLine":		parser.sessionInfo.TestBinaryCommandLine	= value
		case "cherryTestBinaryWorkingDir":		parser.sessionInfo.TestBinaryWorkingDir		= value
		default: log.Println("[qpa] warning: unknown #sessionInfo item")
	}
}

func (parser *LogContainerParser) beginSession () {
	parser.resultQueue <- EventSessionInfoRead {
		sessionInfo: parser.sessionInfo,
	}
}

func (parser *LogContainerParser) beginTestCase (casePath string) {
	parser.resultQueue <- EventTestCaseStarted {
		testCasePath: casePath,
	}
	parser.currentCasePath = casePath
}

func (parser *LogContainerParser) endTestCase (status TestStatusCode) {
	parser.resultQueue <- EventTestCaseFinished {
		path:		parser.currentCasePath,
		status:		status,
		log:		parser.currentCaseLog.String(),
	}

	parser.currentCasePath = ""
	parser.currentCaseLog.Truncate(0)
}

func parseLogStatusCode (logStatus string) TestStatusCode {
	parsed := parseTestStatusCode(logStatus)
	if parsed == TestStatusCode("") {
		switch logStatus {
			case "Watchdog timeout occurred.":	return TEST_STATUS_CODE_TIMEOUT
			default:							return TEST_STATUS_CODE_CRASH
		}
	} else {
		return parsed
	}
}

func (parser *LogContainerParser) Terminate () {
	if parser.currentCasePath != "" {
		parser.endTestCase(TEST_STATUS_CODE_CRASH)
	}
}

func (parser *LogContainerParser) IsInsideSession () bool {
	return parser.isInsideSession
}

func (parser *LogContainerParser) ParseLine (line string) {
	if len(line) == 0 { return }

	if line[0] != '#' && parser.currentCasePath != "" {
		// Usual case.
		parser.currentCaseLog.WriteString(line)
		parser.currentCaseLog.WriteString("\n")
	} else {
		directive, rest := split2(line, " ")

		switch directive {
			case "#sessionInfo":
				if parser.isInsideSession {
					log.Println("[qpa] warning: #sessionInfo after #beginSession; ignoring")
				} else {
					parser.parseSessionInfo(rest)
				}

			case "#beginSession":
				if rest != "" { log.Println("[qpa] warning: garbage after #beginSession; ignoring garbage") }
				if parser.isInsideSession {
					log.Println("[qpa] warning: double #beginSession; ignoring")
				} else {
					parser.beginSession()
					parser.isInsideSession = true
				}

			case "#beginTestCaseResult":
				if !parser.isInsideSession {
					log.Println("[qpa] warning: first test case before #beginSession; ignoring")
				} else {
					if rest == "" {
						log.Println("[qpa] warning: empty test case name in #beginTestCaseResult; ignoring test case")
					} else {
						if parser.currentCasePath != "" {
							log.Println("[qpa] warning: #beginTestCaseResult when already parsing a test case; terminating current case")
							parser.endTestCase(TEST_STATUS_CODE_INTERNAL_ERROR)
						}
						parser.beginTestCase(rest)
					}
				}

			case "#endTestCaseResult":
				if rest != "" { log.Println("[qpa] warning: garbage after #endTestCaseResult; ignoring garbage") }
				if parser.currentCasePath == "" {
					log.Println("[qpa] warning: #endTestCaseResult when not parsing a test case; ignoring")
				} else {
					parser.endTestCase(TestStatusCode(""))
				}

			case "#terminateTestCaseResult":
				if parser.currentCasePath == "" {
					log.Println("[qpa] warning: #terminateTestCaseResult when not parsing a test case; ignoring")
				} else {
					parser.endTestCase(parseLogStatusCode(rest))
				}

			case "#endSession":
				if rest != "" { log.Println("[qpa] warning: garbage after #endSession; ignoring garbage") }
				if !parser.isInsideSession {
					log.Println("[qpa] warning: #endSession when not parsing a session; ignoring")
				} else {
					if parser.currentCasePath != "" {
						log.Println("[qpa] warning: #endSession inside test case result; terminating current case")
						parser.endTestCase(TEST_STATUS_CODE_INTERNAL_ERROR)
					}
					parser.isInsideSession = false
				}

			default:
				if parser.currentCasePath != "" {
					parser.currentCaseLog.WriteString(line)
					parser.currentCaseLog.WriteString("\n")
				}
		}
	}
}

func CreateLogContainerWriter (dst io.Writer) *LogContainerWriter {
	writer := &LogContainerWriter {
		dst:				dst,
		err:				nil,
		isSessionStarted:	false,
		isFinished:			false,
	}

	return writer
}

func (writer *LogContainerWriter) BeginSession (batch BatchResult, config DeviceConfig) error {
	if writer.isSessionStarted { panic("[qpa] writer.BeginSession called twice") }

	writer.writeSessionInfo(BatchSessionInfo {
		ADBSerialNumber:		config.ADBSerialNumber,

		ReleaseName:			batch.ReleaseName,
		ReleaseId:				batch.ReleaseId,
		BuildTargetName:		batch.BuildTargetName,
		ResultName:				batch.Name,
		Timestamp:				batch.Timestamp,

		TargetAddress:			batch.ExecParams.TargetAddress,
		TargetPort:				batch.ExecParams.TargetPort,
		SpawnLocalProcess:		batch.ExecParams.SpawnLocalProcess,
		DeviceId:				batch.ExecParams.DeviceId,
		TestBinaryName:			batch.ExecParams.TestBinaryName,
		TestBinaryCommandLine:	batch.ExecParams.TestBinaryCommandLine,
		TestBinaryWorkingDir:	batch.ExecParams.TestBinaryWorkingDir,

		CandyTargetName:		batch.CandyTargetName,
		CandyConfigName:		batch.CandyConfigName,
	})
	writer.write("#beginSession\n")
	writer.isSessionStarted = true
	return writer.err
}

func (writer *LogContainerWriter) write (s string) {
	if writer.err == nil {
		_, writer.err = io.WriteString(writer.dst, s)
	}
}

func (writer *LogContainerWriter) WriteTestCaseResult (header TestCaseHeader, result TestCaseResult) error {
	if !writer.isSessionStarted { panic("[qpa] writer.WriteTestCaseResult called before BeginSession") }
	if writer.isFinished { panic("[qpa] writer.WriteTestCaseResult called after Finish") }

	writer.write("#beginTestCaseResult " + result.Path + "\n")
	writer.write(result.Log)

	status := header.Status
	if status == TEST_STATUS_CODE_RUNNING {
		status = TEST_STATUS_CODE_PENDING // \note Export running cases as pending.
	}
	if isTerminatedTestStatusCode(status) {
		writer.write("#terminateTestCaseResult " + testStatusCodeToString(status) + "\n")
	} else {
		writer.write("#endTestCaseResult\n")
	}

	return writer.err
}

func (writer *LogContainerWriter) EndSession () error {
	if !writer.isSessionStarted { panic("[qpa] writer.EndSession called before BeginSession") }
	if writer.isFinished { panic("[qpa] writer.EndSession() called twice") }

	writer.write("#endSession\n")
	writer.isFinished = true
	return writer.err
}

func (writer *LogContainerWriter) writeSessionInfoLine (key, value string) {
	writer.write("#sessionInfo " + key)
	if value != "" {
		writer.write(" " + value)
	}
	writer.write("\n")
}

func timestampToString (t time.Time) string {
	return t.UTC().Format("2006-01-02 15:04:05Z")
}

func isTerminatedTestStatusCode (status TestStatusCode) bool {
	switch status {
		case TEST_STATUS_CODE_TIMEOUT:			return true
		case TEST_STATUS_CODE_CRASH:			return true
		case TEST_STATUS_CODE_INTERNAL_ERROR:	return true
		case TEST_STATUS_CODE_DISABLED:			return true
		case TEST_STATUS_CODE_CANCELED:			return true
		case TEST_STATUS_CODE_PENDING:			return true
		default:								return false
	}
}

func testStatusCodeToString (status TestStatusCode) string {
	return string(status)[3:]
}

func (writer *LogContainerWriter) writeSessionInfo (session BatchSessionInfo) {
	writer.writeSessionInfoLine("adbSerialNumber",				`"` + session.ADBSerialNumber + `"`)

	writer.writeSessionInfoLine("releaseName",					session.ReleaseName)
	writer.writeSessionInfoLine("releaseId",					session.ReleaseId)
	writer.writeSessionInfoLine("targetName",					`"` + session.BuildTargetName + `"`)
	writer.writeSessionInfoLine("resultName",					`"` + session.ResultName + `"`)
	writer.writeSessionInfoLine("timestamp",					timestampToString(session.Timestamp))

	writer.writeSessionInfoLine("cherryTargetAddress",			`"` + session.TargetAddress + `"`)
	writer.writeSessionInfoLine("cherryTargetPort",				strconv.Itoa(session.TargetPort))
	writer.writeSessionInfoLine("cherrySpawnLocalProcess",		`"` + session.SpawnLocalProcess + `"`)
	writer.writeSessionInfoLine("cherryDeviceId",				`"` + session.DeviceId + `"`)
	writer.writeSessionInfoLine("cherryTestBinaryName",			`"` + session.TestBinaryName + `"`)
	writer.writeSessionInfoLine("cherryTestBinaryCommandLine",	`"` + session.TestBinaryCommandLine + `"`)
	writer.writeSessionInfoLine("cherryTestBinaryWorkingDir",	`"` + session.TestBinaryWorkingDir + `"`)

	// \note These two are legacy. Only write them if they're nonempty, i.e. this batch
	//		 has been imported from a qpa that had them.
	if session.CandyTargetName != "" {
		writer.writeSessionInfoLine("candyTargetName",	`"` + session.CandyTargetName + `"`)
	}
	if session.CandyConfigName != "" {
		writer.writeSessionInfoLine("configName",		`"` + session.CandyConfigName + `"`)
	}
}
