package com.fairphone.hiccup.app;

import android.util.Log;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

/**
 * Copyright 2016 Fairphone B.V.
 *
 * 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.
 */

public class BoardDate {

    /* The board date is stored in an ingenious format:
     * Read the binary data of the file, convert it to hex
     * and you get the decimal representation of the date.
     * Speechless.
     */

    private static final String BOARD_DATE_FILE = "/persist/board_date.bin";
    private static final String BOARD_DATE_FORMAT = "yyyyMMddHH";
    private static final String BOARD_DATE_TIMEZONE = "Asia/Shanghai";
    private static final long DEFAULT_BOARD_DATE_TIMESTAMP = 0L;

    private static Date boardDate = null;

    private static final String TAG = "HICCUP";

    public static Date getBoardDate() {
        if (boardDate== null) {
            boardDate = readBoardDate();
        }
        return boardDate;
    }

    private static Date readBoardDate() {
        Date boardDate;

        try {
            final byte[] boardFile = getBoardDateFileInByteArray();
            final String strDate = bytesToHex(boardFile);
            final SimpleDateFormat format = new SimpleDateFormat(BOARD_DATE_FORMAT, Locale.US);
            format.setTimeZone(TimeZone.getTimeZone(BOARD_DATE_TIMEZONE));

            // we want to ignore the time for anonymity
            boardDate = format.parse(strDate.substring(0,10));
        } catch (Exception e) {
            Log.e(TAG, "Unknown error while reading board date; using default", e);
            boardDate = new Date(DEFAULT_BOARD_DATE_TIMESTAMP);
        }

        return boardDate;
    }

    private static byte[] getBoardDateFileInByteArray()
    {
        File file = new File(BOARD_DATE_FILE);
        byte[] fileData = new byte[(int) file.length()];
        DataInputStream dis = null;
        try {
            dis = new DataInputStream(new FileInputStream(file));
            dis.read(fileData);
            dis.close();
        } catch (FileNotFoundException e) {
            Log.e(TAG,"BoardDateFile not found", e);
        } catch (IOException e) {
            Log.e(TAG, "BoardDateFile IOException", e);
        }
        finally {
            return fileData;
        }
    }

    public static String bytesToHex(byte[] bytes) {
        final char[] hexArray = "0123456789ABCDEF".toCharArray();
        char[] hexChars = new char[bytes.length * 2];
        for ( int j = 0; j < bytes.length; j++ ) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }
}

