/*-
 * ============LICENSE_START=======================================================
 * OSAM
 * ================================================================================
 * Copyright (C) 2018 AT&T
 * ================================================================================
 * 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.
 * ============LICENSE_END=========================================================
 */



package org.onap.osam.controllers;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.onap.osam.aai.AaiResponse;
import org.onap.osam.services.IAaiService;
import org.onap.portalsdk.core.controller.UnRestrictedBaseController;
import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
import org.onap.portalsdk.core.util.SystemProperties;
import org.onap.osam.dao.FnAppDoaImpl;
import org.onap.osam.model.GitRepositoryState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

@RestController
@RequestMapping("/")
public class PodDemoController extends UnRestrictedBaseController {

    @Autowired
    private IAaiService aaiService;

    private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(PodDemoController.class);

    final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");

    private static final String HEALTH_CHECK_PATH = "/healthCheck";
    private static final String GIT_PROPERTIES_FILENAME = "git.properties";

    /**
     * Model for JSON response with health-check results.
     */
    public class HealthStatus {
        // Either 200 or 500
        public int statusCode;

        // Additional detail in case of error, empty in case of success.
        public String message;

        public String date;

        public HealthStatus(int code, String msg) {
            this.statusCode = code;
            this.message = msg;
        }

        public HealthStatus(int code, String date, String msg) {
            this.statusCode = code;
            this.message = msg;
            this.date = date;
        }

        public int getStatusCode() {
            return statusCode;
        }

        public void setStatusCode(int code) {
            this.statusCode = code;
        }

        public String getMessage() {
            return message;
        }

        public void setMessage(String msg) {
            this.message = msg;
        }

        public String getDate() {
            return date;
        }

        public void setDate(String date) {
            this.date = date;
        }

    }

    @SuppressWarnings("unchecked")
    public int getProfileCount(String driver, String URL, String username, String password) {
        FnAppDoaImpl doa = new FnAppDoaImpl();
        int count = doa.getProfileCount(driver, URL, username, password);
        return count;
    }


    /**
     * Obtain the HealthCheck Status from the System.Properties file.
     * Used by IDNS for redundancy
     *
     * @return ResponseEntity The response entity
     * @throws IOException Signals that an I/O exception has occurred.
     */
    @RequestMapping(value = "/healthCheck", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public HealthStatus gethealthCheckStatusforIDNS() {

        String driver = SystemProperties.getProperty("db.driver");
        String URL = SystemProperties.getProperty("db.connectionURL");
        String username = SystemProperties.getProperty("db.userName");
        String password = SystemProperties.getProperty("db.password");

        LOGGER.debug(EELFLoggerDelegate.debugLogger, "driver ::" + driver);
        LOGGER.debug(EELFLoggerDelegate.debugLogger, "URL::" + URL);
        LOGGER.debug(EELFLoggerDelegate.debugLogger, "username::" + username);
        LOGGER.debug(EELFLoggerDelegate.debugLogger, "password::" + password);


        HealthStatus healthStatus = null;
        try {
            LOGGER.debug(EELFLoggerDelegate.debugLogger, "Performing health check");
            int count = getProfileCount(driver, URL, username, password);
            LOGGER.debug(EELFLoggerDelegate.debugLogger, "count:::" + count);
            healthStatus = new HealthStatus(200, "health check succeeded");
        } catch (Exception ex) {

            LOGGER.error(EELFLoggerDelegate.errorLogger, "Failed to perform health check", ex);
            healthStatus = new HealthStatus(500, "health check failed: " + ex.toString());
        }
        return healthStatus;
    }

    @RequestMapping(value = "/pods/getAndSaveAll", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<String> getAndSaveAllPods() {

        return (new ResponseEntity<>("", HttpStatus.OK));
    }

    @RequestMapping(value = {"/aai_test"}, method = RequestMethod.GET)
    public ResponseEntity<String> getAicZones(HttpServletRequest request) throws IOException {
        LOGGER.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== getAicZones controller start");
        AaiResponse response = aaiService.getAaiZones();
        return aaiResponseToResponseEntity(response);
    }

    private ResponseEntity<String> aaiResponseToResponseEntity(AaiResponse aaiResponseData)
            throws IOException {
        ResponseEntity<String> responseEntity;
        ObjectMapper objectMapper = new ObjectMapper();
        if (aaiResponseData.getHttpCode() == 200) {
            responseEntity = new ResponseEntity<String>(objectMapper.writeValueAsString(aaiResponseData.getT()), HttpStatus.OK);
        } else {
            responseEntity = new ResponseEntity<String>(aaiResponseData.getErrorMessage(), HttpStatus.valueOf(aaiResponseData.getHttpCode()));
        }
        return responseEntity;
    }

    @RequestMapping(value = "/commitInfo", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public GitRepositoryState getCommitInfo() throws IOException {
        Properties properties = new Properties();
        properties.load(getClass().getClassLoader().getResourceAsStream(GIT_PROPERTIES_FILENAME));
        return new GitRepositoryState(properties);
    }
}

