/*
  Copyright 2021 Grégory Soutadé

  This file is part of libgourou.

  libgourou is free software: you can redistribute it and/or modify
  it under the terms of the GNU Lesser General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  libgourou is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public License
  along with libgourou. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _DEVICE_H_
#define _DEVICE_H_

namespace gourou
{
    class DRMProcessor;

    /**
     * @brief This class is a container for device.xml (device info) and devicesalt (device private key). It should not be used by user.
     */
    class Device
    {
    public:
	static const int DEVICE_KEY_SIZE   = 16;
	static const int DEVICE_SERIAL_LEN = 10;

	/**
	 * @brief Main Device constructor
	 *
	 * @param processor      Instance of DRMProcessor
	 * @param deviceFile     Path of device.xml
	 * @param deviceKeyFile  Path of devicesalt
	 */
	Device(DRMProcessor* processor, const std::string& deviceFile, const std::string& deviceKeyFile);

	/**
	 * @brief Return value of devicesalt file (DEVICE_KEY_SIZE len)
	 */
	const unsigned char* getDeviceKey();

	/**
	 * @brief Get one value of device.xml (deviceClass, deviceSerial, deviceName, deviceType, hobbes, clientOS, clientLocale)
	 */
	std::string getProperty(const std::string& property, const std::string& _default=std::string(""));
	std::string operator[](const std::string& property);

	/**
	 * @brief Create device.xml and devicesalt files when they did not exists
	 *
	 * @param processor      Instance of DRMProcessor
	 * @param dirName        Directory where to put files (.adept)
	 * @param hobbes         Hobbes (client version) to set
	 * @param randomSerial   Create a random serial (new device each time) or not (serial computed from machine specs)
	 */
	static Device* createDevice(DRMProcessor* processor, const std::string& dirName, const std::string& hobbes, bool randomSerial);
	
    private:
	DRMProcessor* processor;
        std::string deviceFile;
        std::string deviceKeyFile;
	unsigned char deviceKey[DEVICE_KEY_SIZE];
	std::map<std::string, std::string> properties;

	Device(DRMProcessor* processor);
	
	std::string makeFingerprint(const std::string& serial);
	std::string makeSerial(bool random);
	void parseDeviceFile();
	void parseDeviceKeyFile();
	void createDeviceFile(const std::string& hobbes, bool randomSerial);
	void createDeviceKeyFile();
    };
}

#endif