/*
 * Copyright (c) 2017 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 com.android.vts.entity;

import com.android.vts.entity.TestCaseRunEntity.TestCase;
import com.google.appengine.api.datastore.Entity;
import com.googlecode.objectify.annotation.Cache;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.Index;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import lombok.Data;
import lombok.NoArgsConstructor;

import static com.googlecode.objectify.ObjectifyService.ofy;

@com.googlecode.objectify.annotation.Entity(name = "TestStatus")
@Cache
@Data
@NoArgsConstructor
/** Entity describing test status. */
public class TestStatusEntity implements DashboardEntity {
    protected static final Logger logger = Logger.getLogger(TestStatusEntity.class.getName());

    public static final String KIND = "TestStatus";

    // Property keys
    public static final String PASS_COUNT = "passCount";
    public static final String FAIL_COUNT = "failCount";
    public static final String UPDATED_TIMESTAMP = "updatedTimestamp";

    protected static final String FAILING_IDS = "failingTestcaseIds";
    protected static final String FAILING_OFFSETS = "failingTestcaseOffsets";

    /** ID field */
    @Id private String testName;

    /** Failing Testcase ID List field */
    private List<Long> failingTestcaseIds;

    /** Failing Testcase Offsets List field */
    private List<Integer> failingTestcaseOffsets;

    /** pass count field */
    @Index private int passCount;

    /** fail count field */
    @Index private int failCount;

    /** updated timestamp field */
    @Index private long updatedTimestamp;

    @Ignore private List<TestCaseReference> failingTestCases;

    /** Object representing a reference to a test case. */
    public static class TestCaseReference {
        public final long parentId;
        public final int offset;

        /**
         * Create a test case reference.
         *
         * @param parentId The ID of the TestCaseRunEntity containing the test case.
         * @param offset The offset of the test case into the TestCaseRunEntity.
         */
        public TestCaseReference(long parentId, int offset) {
            this.parentId = parentId;
            this.offset = offset;
        }

        /**
         * Create a test case reference.
         *
         * @param testCase The TestCase to reference.
         */
        public TestCaseReference(TestCase testCase) {
            this(testCase.parentId, testCase.offset);
        }
    }

    /**
     * Create a TestEntity object with status metadata.
     *
     * @param testName The name of the test.
     * @param timestamp The timestamp indicating the most recent test run event in the test state.
     * @param passCount The number of tests passing up to the timestamp specified.
     * @param failCount The number of tests failing up to the timestamp specified.
     * @param failingTestCases The TestCaseReferences of the last observed failing test cases.
     */
    public TestStatusEntity(
        String testName,
        long timestamp,
        int passCount,
        int failCount,
        List<TestCaseReference> failingTestCases) {
        this.testName = testName;
        this.updatedTimestamp = timestamp;
        this.passCount = passCount;
        this.failCount = failCount;
        this.failingTestCases = failingTestCases;
    }

    /**
     * Create a TestEntity object without metadata.
     *
     * @param testName The name of the test.
     */
    public TestStatusEntity(String testName) {
        this(testName, 0, -1, -1, new ArrayList<TestCaseReference>());
    }

    /** Saving function for the instance of this class */
    @Override
    public com.googlecode.objectify.Key<TestStatusEntity> save() {
        return ofy().save().entity(this).now();
    }

    public Entity toEntity() {
        Entity testEntity = new Entity(KIND, this.testName);
        if (this.updatedTimestamp >= 0 && this.passCount >= 0 && this.failCount >= 0) {
            testEntity.setProperty(UPDATED_TIMESTAMP, this.updatedTimestamp);
            testEntity.setProperty(PASS_COUNT, this.passCount);
            testEntity.setProperty(FAIL_COUNT, this.failCount);
            if (this.failingTestCases.size() > 0) {
                List<Long> failingTestcaseIds = new ArrayList<>();
                List<Integer> failingTestcaseOffsets = new ArrayList<>();
                for (TestCaseReference testCase : this.failingTestCases) {
                    failingTestcaseIds.add(testCase.parentId);
                    failingTestcaseOffsets.add(testCase.offset);
                }
                testEntity.setUnindexedProperty(FAILING_IDS, failingTestcaseIds);
                testEntity.setUnindexedProperty(FAILING_OFFSETS, failingTestcaseOffsets);
            }
        }
        return testEntity;
    }

    /**
     * Convert an Entity object to a TestEntity.
     *
     * @param e The entity to process.
     * @return TestEntity object with the properties from e processed, or null if incompatible.
     */
    @SuppressWarnings("unchecked")
    public static TestStatusEntity fromEntity(Entity e) {
        if (!e.getKind().equals(KIND) || e.getKey().getName() == null) {
            logger.log(Level.WARNING, "Missing test attributes in entity: " + e.toString());
            return null;
        }
        String testName = e.getKey().getName();
        long timestamp = 0;
        int passCount = -1;
        int failCount = -1;
        List<TestCaseReference> failingTestCases = new ArrayList<>();
        try {
            if (e.hasProperty(UPDATED_TIMESTAMP)) {
                timestamp = (long) e.getProperty(UPDATED_TIMESTAMP);
            }
            if (e.hasProperty(PASS_COUNT)) {
                passCount = ((Long) e.getProperty(PASS_COUNT)).intValue();
            }
            if (e.hasProperty(FAIL_COUNT)) {
                failCount = ((Long) e.getProperty(FAIL_COUNT)).intValue();
            }
            if (e.hasProperty(FAILING_IDS) && e.hasProperty(FAILING_OFFSETS)) {
                List<Long> ids = (List<Long>) e.getProperty(FAILING_IDS);
                List<Long> offsets = (List<Long>) e.getProperty(FAILING_OFFSETS);
                if (ids.size() == offsets.size()) {
                    for (int i = 0; i < ids.size(); i++) {
                        failingTestCases.add(
                            new TestCaseReference(ids.get(i), offsets.get(i).intValue()));
                    }
                }
            }
        } catch (ClassCastException exception) {
            // Invalid contents or null values
            logger.log(Level.WARNING, "Error parsing test entity.", exception);
        }
        return new TestStatusEntity(testName, timestamp, passCount, failCount, failingTestCases);
    }
}
